Пример #1
0
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 );
}
Пример #2
0
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 );
}
Пример #3
0
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);
        }
    }
}
Пример #4
0
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 );
}
Пример #5
0
    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;
    }