Пример #1
0
    ///  Dimensions of parametric_coordinates and input_phy_points are required to be ([P],[D])
    /// output_values: ([P], [DOF])
    void StringFunction::operator()(MDArray& input_phy_points, MDArray& output_values,
                                    const stk::mesh::Entity& element, const MDArray& parametric_coordinates, double time_value_optional) 
    {
      PRINT("tmp srk StringFunction::operator(element) getName()= " << getName() << " input_phy_points= " << input_phy_points << " output_values= " << output_values);

      argsAreValid(input_phy_points, output_values);
      argsAreValid(parametric_coordinates, output_values);

      m_element = &element;
      m_have_element = true;
      VERIFY_OP(parametric_coordinates.rank(), ==, 2, "StringFunction::operator() parametric_coordinates rank bad");
      m_parametric_coordinates = MDArray(1, parametric_coordinates.dimension(1));
      int nPoints=parametric_coordinates.dimension(0);
      int spaceDim = parametric_coordinates.dimension(1);
      for (int iPoint = 0; iPoint < nPoints; iPoint++)
        {
          for (int iSpace=0; iSpace < spaceDim; iSpace++)
            m_parametric_coordinates(0, iSpace)=parametric_coordinates(iPoint, iSpace);
          (*this)(input_phy_points, output_values, time_value_optional);
        }

      // reset this else we won't be able to reuse this object correctly
      m_have_element = false;
      m_element = 0;

      // *  Dimensions of parametric_coordinates are required to be ([P],[D])
      //FieldFunction:: void operator()(const stk::mesh::Entity *element, const MDArray& parametric_coordinates, MDArray& out);

    }
Пример #2
0
    void StringFunction::operator()(MDArray& inp, MDArray& out, double time_value_optional)
    {
      EXCEPTWATCH;
      argsAreValid(inp, out);
      PRINT("tmp srk StringFunction::operator() getName()= " << getName() << " inp= " << inp << " out= " << out);

      int domain_rank   = m_domain_dimensions.size();
      int codomain_rank = m_codomain_dimensions.size();

      // FIXME move to argsAreValid
      VERIFY_OP(domain_rank, ==, 1, "StringFunction::operator(): must specify domain Dimensions as rank 1 (for now)");
      VERIFY_OP(codomain_rank, ==, 1, "StringFunction::operator(): must specify codomain Dimensions as rank 1 (for now)");

      int inp_rank      = inp.rank();
      int out_rank      = out.rank();
      int inp_offset    = inp_rank - domain_rank;
      int out_offset    = out_rank - codomain_rank;

      // returns 1,1,1,... etc. if that dimension doesn't exist
      enum { maxRank = 3};
      VERIFY_OP_ON(inp_rank, <=,  maxRank, "StringFunction::operator() input array rank too large");
      VERIFY_OP_ON(out_rank, <=,  maxRank, "StringFunction::operator() output array rank too large");
      int n_inp_points[maxRank] = {1,1,1};
      int n_out_points[maxRank] = {1,1,1};
      first_dimensions(inp, inp_offset, n_inp_points, maxRank);  
      first_dimensions(out, out_offset, n_out_points, maxRank);  

      int nInDim  = m_domain_dimensions[0];
      int nOutDim = m_codomain_dimensions[0];

      MDArray inp_loc(nInDim);
      MDArray out_loc(nOutDim);

      int iDim[maxRank-1] = {0,0};
      double *xyzt[] = {&m_x, &m_y, &m_z, &m_t};

      PRINT("getName()= " << getName() << " n_inp_points= " << n_inp_points[0] << " " << n_inp_points[1] << " " << n_inp_points[2] << " nInDim= " << nInDim);

      m_t = time_value_optional;
      for (iDim[0] = 0; iDim[0] < n_inp_points[0]; iDim[0]++)
        {
          for (iDim[1] = 0; iDim[1] < n_inp_points[1]; iDim[1]++)
            {
              for (int id = 0; id < nInDim; id++)
                {
                  switch (inp_rank)
                    {
                    case 3:
                      inp_loc(id) = inp(iDim[0], iDim[1], id);
                      *xyzt[id] = inp(iDim[0], iDim[1], id);
                      break;
                    case 2:
                      inp_loc(id) = inp(iDim[0], id);
                      *xyzt[id] = inp(iDim[0], id);
                      break;
                    case 1:
                      inp_loc(id) = inp( id);
                      *xyzt[id] = inp( id);
                      break;
                    }
                }

              if (m_func_to_value.size())
                {
                  evalFunctions(inp_loc, time_value_optional);
                }

              //Save the evaluations slightly differently whether it's a scalar or vector valued function
              if ((int)m_v.size() != nOutDim)
                {
                  m_v.resize(nOutDim);
                }

              PRINT("getName()= " << getName() << " about to evaluate m_functionExpr... iDim[0] = " << iDim[0] << " iDim[1]= " << iDim[1]);
              if(nOutDim == 1)
                m_v[0] = m_functionExpr.evaluate();
              else
                m_functionExpr.evaluate();
              PRINT("getName()= " << getName() << " done to evaluate m_functionExpr... iDim[0] = " << iDim[0] << " iDim[1]= " << iDim[1]);

              for (int iOutDim = 0; iOutDim < nOutDim; iOutDim++)
                {
                  switch (out_rank)
                    {
                    case 1: out(iOutDim)                   = m_v[iOutDim]; break;
                    case 2: out(iDim[0], iOutDim)          = m_v[iOutDim]; break;
                    case 3: out(iDim[0], iDim[1], iOutDim) = m_v[iOutDim]; break;
                    default:
                      VERIFY_1("StringFunction::operator() bad output rank");
                    }
                }
            }
        }
      PRINT("getName()= " << getName() << " done in operator()");
    }
Пример #3
0
    /** Evaluate the function at this input point (or points) returning value(s) in output_field_values
     *
     *   In the following, the arrays are dimensioned using the notation (from Intrepid's doc):
     *
     *   [C]         - num. integration domains (cells/elements)
     *   [F]         - num. Intrepid "fields" (number of bases within an element == num. nodes typically)
     *   [P]         - num. integration (or interpolation) points within the element
     *   [D]         - spatial dimension
     *   [D1], [D2]  - spatial dimension
     *
     *   Locally, we introduce this notation:
     *
     *   [DOF]       - number of degrees-of-freedom per node of the interpolated stk Field.  For example, a vector field in 3D has [DOF] = 3
     *
     *  Dimensions of input_phy_points are required to be either ([D]) or ([P],[D])
     *  Dimensions of output_field_values are required to be ([DOF]) or ([P],[DOF]) respectively
     *
     *  [R] is used for the rank of MDArray's
     */
    void FieldFunction::operator()(MDArray& input_phy_points, MDArray& output_field_values, double time)
    {
      EXCEPTWATCH;
      argsAreValid(input_phy_points, output_field_values);

      m_found_on_local_owned_part = false;

      //// single point only (for now)
      unsigned found_it = 0;

      int D_ = last_dimension(input_phy_points);
      MDArray found_parametric_coordinates_one(1, D_);
      setup_searcher(D_);

      MDArray output_field_values_local = output_field_values;
      int R_output = output_field_values.rank();

      int R_input = input_phy_points.rank();
      int P_ = (R_input == 1 ? 1 : input_phy_points.dimension(R_input-2));

      // FIXME for tensor valued fields
      int DOF_ = last_dimension(output_field_values_local);

      MDArray input_phy_points_one(1,D_);
      MDArray output_field_values_one(1,DOF_);

      int C_ = 1;
      if (R_input == 3)
        {
          C_ = input_phy_points.dimension(0);
        }
      for (int iC = 0; iC < C_; iC++)
        {
          for (int iP = 0; iP < P_; iP++)
            {
              for (int iD = 0; iD < D_; iD++)
                {
                  switch(R_input)
                    {
                    case 1: input_phy_points_one(0, iD) = input_phy_points(iD); break;
                    case 2: input_phy_points_one(0, iD) = input_phy_points(iP, iD); break;
                    case 3: input_phy_points_one(0, iD) = input_phy_points(iC, iP, iD); break;
                    default: VERIFY_1("bad rank");
                    }
                }

              const stk_classic::mesh::Entity *found_element = 0;
              {
                EXCEPTWATCH;
                //if (m_searchType==STK_SEARCH) std::cout << "find" << std::endl;
                found_element = m_searcher->findElement(input_phy_points_one, found_parametric_coordinates_one, found_it, m_cachedElement);
                //if (m_searchType==STK_SEARCH)                std::cout << "find..done found_it=" << found_it << std::endl;
              }

              // if found element on the local owned part, evaluate
              if (found_it)
                {
                  m_found_on_local_owned_part = true;
                  if (( EXTRA_PRINT) && m_searchType==STK_SEARCH)
                    std::cout << "FieldFunction::operator() found element # = " << found_element->identifier() << std::endl;

                  (*this)(input_phy_points_one, output_field_values_one, *found_element, found_parametric_coordinates_one);

                  for (int iDOF = 0; iDOF < DOF_; iDOF++)
                    {
                      switch (R_output)
                        {
                        case 1: output_field_values_local( iDOF)        = output_field_values_one(0, iDOF); break;
                        case 2: output_field_values_local(iP, iDOF)     = output_field_values_one(0, iDOF); break;
                        case 3: output_field_values_local(iC, iP, iDOF) = output_field_values_one(0, iDOF); break;
                        default: VERIFY_1("bad rank");
                        }
                    }
                }
              else
                {
                  if (!m_parallelEval)
                    {
                      std::cout << "P[" << Util::get_rank() << "] FieldFunction::operator() found_it = " << found_it << " points= "
                                << input_phy_points_one
                                << std::endl;

                      throw std::runtime_error("FieldFunction::operator() in local eval mode and didn't find element - logic error");
                    }
                  double max_val = std::numeric_limits<double>::max();
                  output_field_values_local.initialize(max_val);
                }

              // make sure it is found somewhere
              if (m_parallelEval)
                {
                  all_reduce( m_bulkData->parallel() , ReduceMax<1>( & found_it ) );
                }

              if (EXTRA_PRINT) std::cout << "FieldFunction::operator() global found_it = " << found_it << std::endl;

              if (!found_it)
                {
                  throw std::runtime_error("FieldFunction::operator() couldn't find element");
                }

              if (m_parallelEval)
                {
                  stk_percept_global_lex_min( m_bulkData->parallel(), output_field_values.size(), &output_field_values_local[0], &output_field_values[0]);
                }
              else
                {
                  output_field_values = output_field_values_local;
                }
              m_cachedElement = found_element;
            }
        }

    }