void IntrepidKernel<Scalar>::jacobianDet( Scalar &determinant, const double param_coords[3], const iMesh_Instance mesh, const iBase_EntityHandle physical_cell ) { int error = 0; iBase_EntityHandle *element_nodes = 0; int element_nodes_allocated = 0; int element_nodes_size = 0; iMesh_getEntAdj( mesh, physical_cell, iBase_VERTEX, &element_nodes, &element_nodes_allocated, &element_nodes_size, &error ); assert( iBase_SUCCESS == error ); TopologyTools::MBCN2Shards( element_nodes, element_nodes_size, this->b_topology ); int coords_allocated = 0; int coords_size = 0; double *coord_array = 0; iMesh_getVtxArrCoords( mesh, element_nodes, element_nodes_size, iBase_INTERLEAVED, &coord_array, &coords_allocated, &coords_size, &error ); assert( iBase_SUCCESS == error ); Teuchos::Tuple<int,3> cell_node_dimensions; cell_node_dimensions[0] = 1; cell_node_dimensions[1] = element_nodes_size; cell_node_dimensions[2] = 3; MDArray cell_nodes( Teuchos::Array<int>(cell_node_dimensions), coord_array ); MDArray reference_coords( 1, 3 ); reference_coords(0,0) = param_coords[0]; reference_coords(0,1) = param_coords[1]; reference_coords(0,2) = param_coords[2]; MDArray jacobian( 1, 1, 3, 3 ); Intrepid::CellTools<double>::setJacobian( jacobian, reference_coords, cell_nodes, d_intrepid_basis->getBaseCellTopology() ); MDArray jacobian_det( 1, 1 ); Intrepid::CellTools<double>::setJacobianDet( jacobian_det, jacobian ); determinant = jacobian_det(0,0); free( element_nodes ); free( coord_array ); }
void IntrepidKernel<Scalar>::transformOperator( Teuchos::ArrayRCP<Scalar> &transformed_values, const Teuchos::ArrayRCP<Scalar> &values, const double param_coords[3], const iMesh_Instance mesh, const iBase_EntityHandle physical_cell ) { int error = 0; iBase_EntityHandle *element_nodes = 0; int element_nodes_allocated = 0; int element_nodes_size = 0; iMesh_getEntAdj( mesh, physical_cell, iBase_VERTEX, &element_nodes, &element_nodes_allocated, &element_nodes_size, &error ); assert( iBase_SUCCESS == error ); TopologyTools::MBCN2Shards( element_nodes, element_nodes_size, this->b_topology ); int coords_allocated = 0; int coords_size = 0; double *coord_array = 0; iMesh_getVtxArrCoords( mesh, element_nodes, element_nodes_size, iBase_INTERLEAVED, &coord_array, &coords_allocated, &coords_size, &error ); assert( iBase_SUCCESS == error ); Teuchos::Tuple<int,3> cell_node_dimensions; cell_node_dimensions[0] = 1; cell_node_dimensions[1] = element_nodes_size; cell_node_dimensions[2] = 3; MDArray cell_nodes( Teuchos::Array<int>(cell_node_dimensions), coord_array ); MDArray jacobian( 1, 1, 3, 3 ); MDArray jacobian_det( 1, 1 ); MDArray jacobian_inv( 1, 1, 3, 3 ); MDArray reference_point( 1, 3 ); reference_point(0,0) = param_coords[0]; reference_point(0,1) = param_coords[1]; reference_point(0,2) = param_coords[2]; if ( this->b_function_space_type == FOOD_HGRAD ) { Intrepid::CellTools<double>::setJacobian( jacobian, reference_point, cell_nodes, d_intrepid_basis->getBaseCellTopology() ); Intrepid::CellTools<double>::setJacobianInv( jacobian_inv, jacobian ); MDArray transformed_grad( 1, this->b_cardinality, 1, 3 ); Teuchos::Tuple<int,3> grad_dimensions; grad_dimensions[0] = this->b_cardinality; grad_dimensions[1] = 1; grad_dimensions[2] = 3; MDArray basis_grad( grad_dimensions, values ); Intrepid::FunctionSpaceTools::HGRADtransformGRAD<double>( transformed_grad, jacobian_inv, basis_grad ); transformed_values = transformed_grad.getData(); } else if ( this->b_function_space_type == FOOD_HDIV ) { } else if ( this->b_function_space_type == FOOD_HCURL ) { } else { testPrecondition( this->b_function_space_type == FOOD_HGRAD || this->b_function_space_type == FOOD_HDIV || this->b_function_space_type == FOOD_HCURL, "Invalid function space type" ); } free( coord_array ); free( element_nodes ); }
void Mesh::buildInternalFaces() { if(faces_built) { return; } faces_built = true; //build naive list of faces int num_naive_faces{0}; for (auto i : IRange(0, nCells())) { num_naive_faces += numCellFaces(getCellType(i)); } internal_faces_.clear(); internal_faces_.reserve(num_naive_faces); std::vector<int> cell_nodes(8); for (auto i : IRange(0, nCells())) { getCellNodes(i, cell_nodes); auto ct = getCellType(i); for(auto f : IRange(0, numCellFaces(ct))) { auto F = CellFace::canonicalCellFace(ct,f); for(auto n : IRange(0,F.n_nodes)) { F.nodes[n] = cell_nodes[F.nodes[n]]; } F.left = i; F.left_flocal = f; F.orient(); internal_faces_.push_back(F); } } std::sort(internal_faces_.begin(), internal_faces_.end(), [](const CellFace &L, const CellFace &R) { return L.nodes < R.nodes; } ); for (auto i : IRange(1, static_cast<int>(internal_faces_.size()))) { auto &F = internal_faces_[i]; auto &Fprev = internal_faces_[i - 1]; if (F.nodes == Fprev.nodes) { Fprev.left = std::max(Fprev.left, F.left); Fprev.right = std::max(Fprev.right, F.right); Fprev.left_flocal = std::max(Fprev.left_flocal, F.left_flocal); Fprev.right_flocal = std::max(Fprev.right_flocal, F.right_flocal); Fprev.left_rot = std::max(Fprev.left_rot, F.left_rot); Fprev.right_rot = std::max(Fprev.right_rot, F.right_rot); } } auto new_end = std::unique(internal_faces_.begin(), internal_faces_.end(), [](const CellFace &L, const CellFace &R) { return L.nodes == R.nodes; }); auto new_size = std::distance(internal_faces_.begin(), new_end); internal_faces_.resize(new_size); internal_faces_.shrink_to_fit(); for (auto i : IRange(0, static_cast<int>(internal_faces_.size()))) { if (internal_faces_[i].left < 0 || internal_faces_[i].right < 0) { boundary_face_idxs_.push_back(i); } } }
void IntrepidKernel<Scalar>::transformPoint( double param_coords[3], const double physical_coords[3], const iMesh_Instance mesh, const iBase_EntityHandle physical_cell ) { int error = 0; iBase_EntityHandle *element_nodes = 0; int element_nodes_allocated = 0; int element_nodes_size = 0; iMesh_getEntAdj( mesh, physical_cell, iBase_VERTEX, &element_nodes, &element_nodes_allocated, &element_nodes_size, &error ); assert( iBase_SUCCESS == error ); TopologyTools::MBCN2Shards( element_nodes, element_nodes_size, this->b_topology ); int coords_allocated = 0; int coords_size = 0; double *coord_array = 0; iMesh_getVtxArrCoords( mesh, element_nodes, element_nodes_size, iBase_INTERLEAVED, &coord_array, &coords_allocated, &coords_size, &error ); assert( iBase_SUCCESS == error ); Teuchos::Tuple<int,3> cell_node_dimensions; cell_node_dimensions[0] = 1; cell_node_dimensions[1] = element_nodes_size; cell_node_dimensions[2] = 3; MDArray cell_nodes( Teuchos::Array<int>(cell_node_dimensions), coord_array ); MDArray reference_point( 1, 3 ); MDArray coords( 1, 3 ); coords(0,0) = physical_coords[0]; coords(0,1) = physical_coords[1]; coords(0,2) = physical_coords[2]; Intrepid::CellTools<double>::mapToReferenceFrame( reference_point, coords, cell_nodes, d_intrepid_basis->getBaseCellTopology(), 0 ); param_coords[0] = reference_point(0,0); param_coords[1] = reference_point(0,1); param_coords[2] = reference_point(0,2); free( element_nodes ); free( coord_array ); }
int FunctionSpaceTools_Test02(const bool verbose) { typedef ValueType value_type; Teuchos::RCP<std::ostream> outStream; Teuchos::oblackholestream bhs; // outputs nothing if (verbose) outStream = Teuchos::rcp(&std::cout, false); else outStream = Teuchos::rcp(&bhs, false); Teuchos::oblackholestream oldFormatState; oldFormatState.copyfmt(std::cout); *outStream \ << "===============================================================================\n" \ << "| |\n" \ << "| Unit Test (FunctionSpaceTools) |\n" \ << "| |\n" \ << "| 1) basic operator transformations and integration in HCURL |\n" \ << "| |\n" \ << "| Questions? Contact Pavel Bochev ([email protected]) or |\n" \ << "| Denis Ridzal ([email protected]). |\n" \ << "| |\n" \ << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" \ << "| Trilinos website: http://trilinos.sandia.gov |\n" \ << "| |\n" \ << "===============================================================================\n"; typedef FunctionSpaceTools<DeviceSpaceType> fst; typedef Kokkos::DynRankView<value_type,DeviceSpaceType> DynRankView; #define ConstructWithLabel(obj, ...) obj(#obj, __VA_ARGS__) int errorFlag = 0; *outStream \ << "\n" << "===============================================================================\n"\ << "| TEST 1: correctness of math operations |\n"\ << "===============================================================================\n"; outStream->precision(20); try { shards::CellTopology cellType = shards::getCellTopologyData< shards::Hexahedron<> >(); // cell type: hex /* Related to cubature. */ DefaultCubatureFactory<double> cubFactory; // create cubature factory int cubDegree = 20; // cubature degree Teuchos::RCP<Cubature<double> > myCub = cubFactory.create(cellType, cubDegree); // create default cubature int spaceDim = myCub->getDimension(); // get spatial dimension int numCubPoints = myCub->getNumPoints(); // get number of cubature points /* Related to basis. */ Basis_HCURL_HEX_I1_FEM<double, FieldContainer<double> > hexBasis; // create H-curl basis on a hex int numFields = hexBasis.getCardinality(); // get basis cardinality /* Cell geometries and orientations. */ int numCells = 4; int numNodes = 8; int numCellData = numCells*numNodes*spaceDim; int numSignData = numCells*numFields; double hexnodes[] = { // hex 0 -- affine -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, // hex 1 -- affine -3.0, -3.0, 1.0, 6.0, 3.0, 1.0, 7.0, 8.0, 0.0, -2.0, 2.0, 0.0, -3.0, -3.0, 4.0, 6.0, 3.0, 4.0, 7.0, 8.0, 3.0, -2.0, 2.0, 3.0, // hex 2 -- affine -3.0, -3.0, 0.0, 9.0, 3.0, 0.0, 15.0, 6.1, 0.0, 3.0, 0.1, 0.0, 9.0, 3.0, 0.1, 21.0, 9.0, 0.1, 27.0, 12.1, 0.1, 15.0, 6.1, 0.1, // hex 3 -- nonaffine -2.0, -2.0, 0.0, 2.0, -1.0, 0.0, 1.0, 6.0, 0.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0 }; double edgesigns[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1 }; /* Computational arrays. */ FieldContainer<double> cub_points(numCubPoints, spaceDim); FieldContainer<double> cub_weights(numCubPoints); FieldContainer<double> cell_nodes(numCells, numNodes, spaceDim); FieldContainer<double> field_signs(numCells, numFields); FieldContainer<double> jacobian(numCells, numCubPoints, spaceDim, spaceDim); FieldContainer<double> jacobian_inv(numCells, numCubPoints, spaceDim, spaceDim); FieldContainer<double> jacobian_det(numCells, numCubPoints); FieldContainer<double> weighted_measure(numCells, numCubPoints); FieldContainer<double> curl_of_basis_at_cub_points(numFields, numCubPoints, spaceDim); FieldContainer<double> transformed_curl_of_basis_at_cub_points(numCells, numFields, numCubPoints, spaceDim); FieldContainer<double> weighted_transformed_curl_of_basis_at_cub_points(numCells, numFields, numCubPoints, spaceDim); FieldContainer<double> stiffness_matrices(numCells, numFields, numFields); FieldContainer<double> value_of_basis_at_cub_points(numFields, numCubPoints, spaceDim); FieldContainer<double> transformed_value_of_basis_at_cub_points(numCells, numFields, numCubPoints, spaceDim); FieldContainer<double> weighted_transformed_value_of_basis_at_cub_points(numCells, numFields, numCubPoints, spaceDim); FieldContainer<double> mass_matrices(numCells, numFields, numFields); /******************* START COMPUTATION ***********************/ // get cubature points and weights myCub->getCubature(cub_points, cub_weights); // fill cell vertex array cell_nodes.setValues(hexnodes, numCellData); // set basis function signs, for each cell field_signs.setValues(edgesigns, numSignData); // compute geometric cell information CellTools<double>::setJacobian(jacobian, cub_points, cell_nodes, cellType); CellTools<double>::setJacobianInv(jacobian_inv, jacobian); CellTools<double>::setJacobianDet(jacobian_det, jacobian); // compute weighted measure fst::computeCellMeasure<double>(weighted_measure, jacobian_det, cub_weights); // Computing stiffness matrices: // tabulate curls of basis functions at (reference) cubature points hexBasis.getValues(curl_of_basis_at_cub_points, cub_points, OPERATOR_CURL); // transform curls of basis functions fst::HCURLtransformCURL<double>(transformed_curl_of_basis_at_cub_points, jacobian, jacobian_det, curl_of_basis_at_cub_points); // multiply with weighted measure fst::multiplyMeasure<double>(weighted_transformed_curl_of_basis_at_cub_points, weighted_measure, transformed_curl_of_basis_at_cub_points); // we can apply the field signs to the basis function arrays, or after the fact, see below fst::applyFieldSigns<double>(transformed_curl_of_basis_at_cub_points, field_signs); fst::applyFieldSigns<double>(weighted_transformed_curl_of_basis_at_cub_points, field_signs); // compute stiffness matrices fst::integrate<double>(stiffness_matrices, transformed_curl_of_basis_at_cub_points, weighted_transformed_curl_of_basis_at_cub_points, COMP_CPP); // Computing mass matrices: // tabulate values of basis functions at (reference) cubature points hexBasis.getValues(value_of_basis_at_cub_points, cub_points, OPERATOR_VALUE); // transform values of basis functions fst::HCURLtransformVALUE<double>(transformed_value_of_basis_at_cub_points, jacobian_inv, value_of_basis_at_cub_points); // multiply with weighted measure fst::multiplyMeasure<double>(weighted_transformed_value_of_basis_at_cub_points, weighted_measure, transformed_value_of_basis_at_cub_points); // compute mass matrices fst::integrate<double>(mass_matrices, transformed_value_of_basis_at_cub_points, weighted_transformed_value_of_basis_at_cub_points, COMP_CPP); // apply field signs (after the fact, as a post-processing step) fst::applyLeftFieldSigns<double>(mass_matrices, field_signs); fst::applyRightFieldSigns<double>(mass_matrices, field_signs); /******************* STOP COMPUTATION ***********************/ /******************* START COMPARISON ***********************/ string basedir = "./testdata"; for (int cell_id = 0; cell_id < numCells-1; cell_id++) { stringstream namestream; string filename; namestream << basedir << "/mass_HCURL_HEX_I1_FEM" << "_" << "0" << cell_id+1 << ".dat"; namestream >> filename; ifstream massfile(&filename[0]); if (massfile.is_open()) { if (compareToAnalytic<double>(&mass_matrices(cell_id, 0, 0), massfile, 1e-10, iprint) > 0) errorFlag++; massfile.close(); } else { errorFlag = -1; std::cout << "End Result: TEST FAILED\n"; return errorFlag; } namestream.clear(); namestream << basedir << "/stiff_HCURL_HEX_I1_FEM" << "_" << "0" << cell_id+1 << ".dat"; namestream >> filename; ifstream stifffile(&filename[0]); if (stifffile.is_open()) { if (compareToAnalytic<double>(&stiffness_matrices(cell_id, 0, 0), stifffile, 1e-10, iprint) > 0) errorFlag++; stifffile.close(); } else { errorFlag = -1; std::cout << "End Result: TEST FAILED\n"; return errorFlag; } } for (int cell_id = 3; cell_id < numCells; cell_id++) { stringstream namestream; string filename; namestream << basedir << "/mass_fp_HCURL_HEX_I1_FEM" << "_" << "0" << cell_id+1 << ".dat"; namestream >> filename; ifstream massfile(&filename[0]); if (massfile.is_open()) { if (compareToAnalytic<double>(&mass_matrices(cell_id, 0, 0), massfile, 1e-4, iprint, INTREPID2_UTILS_SCALAR) > 0) errorFlag++; massfile.close(); } else { errorFlag = -1; std::cout << "End Result: TEST FAILED\n"; return errorFlag; } namestream.clear(); namestream << basedir << "/stiff_fp_HCURL_HEX_I1_FEM" << "_" << "0" << cell_id+1 << ".dat"; namestream >> filename; ifstream stifffile(&filename[0]); if (stifffile.is_open()) { if (compareToAnalytic<double>(&stiffness_matrices(cell_id, 0, 0), stifffile, 1e-4, iprint, INTREPID2_UTILS_SCALAR) > 0) errorFlag++; stifffile.close(); } else { errorFlag = -1; std::cout << "End Result: TEST FAILED\n"; return errorFlag; } } /******************* STOP COMPARISON ***********************/ *outStream << "\n"; } catch (std::logic_error err) { *outStream << "UNEXPECTED ERROR !!! ----------------------------------------------------------\n"; *outStream << err.what() << '\n'; *outStream << "-------------------------------------------------------------------------------" << "\n\n"; errorFlag = -1000; }; if (errorFlag != 0) std::cout << "End Result: TEST FAILED\n"; else std::cout << "End Result: TEST PASSED\n"; // reset format state of std::cout std::cout.copyfmt(oldFormatState); Kokkos::finalize(); return errorFlag; }