コード例 #1
0
void ConjugateGradient::initialize(PatchData &pd, MsqError &err)
{
  if (get_parallel_size())
    MSQ_DBGOUT(2) << "\nP[" << get_parallel_rank() << "] " << "o   Performing Conjugate Gradient optimization.\n";
  else
    MSQ_DBGOUT(2) << "\no   Performing Conjugate Gradient optimization.\n";
  pMemento=pd.create_vertices_memento(err);
}
std::string TerminationCriterion::par_string() 
{
  if (get_parallel_size())
    {
      std::ostringstream str;
      str << "P[" << get_parallel_rank() << "] " + moniker + " ";
      return str.str();
    }
  return moniker + " ";
}
コード例 #3
0
    void PMMParallelReferenceMeshSmoother::run_wrapper( Mesh* mesh,
                                                        ParallelMesh* pmesh,
                                                        MeshDomain* domain,
                                                        Settings* settings,
                                                        QualityAssessor* qa,
                                                        MsqError& err )
    {
      std::cout << "\nP[" << Mesquite::get_parallel_rank() << "] tmp srk PMMParallelReferenceMeshSmoother innerIter= " << innerIter << " parallelIterations= " << parallelIterations << std::endl;

      //if (!get_parallel_rank()) 
      std::cout << "\nP[" << get_parallel_rank() << "] tmp srk PMMParallelReferenceMeshSmoother: running shape improver... \n" << std::endl;

      PerceptMesquiteMesh *pmm = dynamic_cast<PerceptMesquiteMesh *>(mesh);
      PerceptMesh *eMesh = pmm->getPerceptMesh();
      m_pmm= pmm;
      m_eMesh = eMesh;
      m_num_nodes = m_eMesh->get_number_nodes();

      print_comm_list(*eMesh->get_bulk_data(), false);

      stk::mesh::FieldBase *coord_field           = eMesh->get_coordinates_field();
      stk::mesh::FieldBase *coord_field_current   = coord_field;
      stk::mesh::FieldBase *coord_field_projected = eMesh->get_field("coordinates_N"); 
      stk::mesh::FieldBase *coord_field_original  = eMesh->get_field("coordinates_NM1");
      stk::mesh::FieldBase *coord_field_lagged    = eMesh->get_field("coordinates_lagged");

      m_coord_field_original  = coord_field_original;
      m_coord_field_projected = coord_field_projected;
      m_coord_field_lagged    = coord_field_lagged;
      m_coord_field_current   = coord_field_current;

      eMesh->copy_field(coord_field_lagged, coord_field_original);

      // untangle
      PMMSmootherMetricUntangle untangle_metric(eMesh);

      // shape-size-orient smooth
      PMMSmootherMetricShapeSizeOrient shape_metric(eMesh);

      // shape
      PMMSmootherMetricShapeB1 shape_b1_metric(eMesh);

      // scaled jacobian
      PMMSmootherMetricScaledJacobianElemental scaled_jac_metric(eMesh);

      // scaled jacobian - nodal
      PMMSmootherMetricScaledJacobianNodal scaled_jac_metric_nodal(eMesh);

      //double omegas[] = {0.0, 0.001, 0.01, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0};
      //double omegas[] = {0.001, 1.0};
      //double omegas[] = { 0.001, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.2, 0.4, 0.45,0.46,0.47,0.48,0.49,0.5,0.52,0.54,0.56,0.59, 0.6, 0.8, 1.0};
      double omegas[] = { 1.0};
      //double omegas[] = {0.0, 0.001, 0.01, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2, 0.4, 0.6, 0.8, 1.0};
      int nomega = sizeof(omegas)/sizeof(omegas[0]);
      
      for (int outer = 0; outer < nomega; outer++)
        {
          double omega = (outer < nomega ? omegas[outer] : 1.0);
          m_omega = omega;
          m_omega_prev = omega;
          if (outer > 0) m_omega_prev = omegas[outer-1];

          // set current state and evaluate mesh validity (current = omega*project + (1-omega)*original)
          eMesh->nodal_field_axpbypgz(omega, coord_field_projected, (1.0-omega), coord_field_original, 0.0, coord_field_current);

          int num_invalid = PMMParallelShapeImprover::parallel_count_invalid_elements(m_eMesh);

          if (!get_parallel_rank()) 
            std::cout << "\ntmp srk PMMParallelReferenceMeshSmoother num_invalid current= " << num_invalid << " for outer_iter= " << outer 
                      << " omega= " << omega
                      << (num_invalid ? " WARNING: invalid elements exist before Mesquite smoothing" : " OK")
                      << std::endl;
          //if (num_invalid) return;
          m_num_invalid = num_invalid;
          m_untangled = (m_num_invalid == 0);

          int iter_all=0;

          int do_anim = 0; // = frequency of anim writes
          if (do_anim)
            {
              eMesh->save_as("anim_all."+toString(iter_all)+".e");
            }

          for (int stage = 0; stage < 2; stage++)
            {
              m_stage = stage;
              if (stage==0) 
                {
                  m_metric = &untangle_metric;
                  //m_metric = &scaled_jac_metric_nodal;
                }
              else 
                {
                  int num_invalid_1 = PMMParallelShapeImprover::parallel_count_invalid_elements(m_eMesh);
                  VERIFY_OP_ON(num_invalid_1, ==, 0, "Invalid elements exist for start of stage 2, aborting");

                  //m_metric = &shape_metric;
                  m_metric = &shape_b1_metric;
                  //m_metric = &scaled_jac_metric;

                }

              for (int iter = 0; iter < innerIter; ++iter, ++iter_all)
                {
                  m_iter = iter;
                  int num_invalid_0 = PMMParallelShapeImprover::parallel_count_invalid_elements(m_eMesh);
                  m_num_invalid = num_invalid_0;

                  //               if (!get_parallel_rank() && num_invalid_0) 
                  //                 std::cout << "\ntmp srk PMMParallelReferenceMeshSmoother num_invalid current= " << num_invalid_0 
                  //                           << (num_invalid ? " WARNING: invalid elements exist before Mesquite smoothing" : "OK")
                  //                           << std::endl;

                  m_global_metric = run_one_iteration(mesh, domain, err);

                  sync_fields(iter);
                  num_invalid_0 = PMMParallelShapeImprover::parallel_count_invalid_elements(m_eMesh);
                  m_num_invalid = num_invalid_0;
                  bool conv = check_convergence();
                  if (!get_parallel_rank())
                  {
                    std::cout << "P[" << get_parallel_rank() << "] " << "tmp srk iter= " << iter << " dmax= " << m_dmax << " m_dnew= " << m_dnew 
                              << " m_d0= " << m_d0 << " m_alpha= " << m_alpha << " m_grad_norm= " << m_grad_norm << " m_scaled_grad_norm = " << m_scaled_grad_norm
                              << " num_invalid= " << num_invalid_0 
                              << " m_global_metric= " << m_global_metric << " m_untangled= " << m_untangled
                              << std::endl;
                  }

                  if (do_anim)
                    {
                       eMesh->save_as("iter_"+toString(outer)+"_"+toString(stage)+"."+toString(iter+1)+".e");
                       if (iter_all % do_anim == 0) eMesh->save_as("anim_all."+toString(iter_all+1)+".e");
                    }

                  if (!m_untangled && m_num_invalid == 0)
                    {
                      m_untangled = true;
                    }
                  if (conv && m_untangled) break;
                  //if (iter == 5) break;
                  //if (iter == 0) exit(1);
                }

              eMesh->save_as("outer_iter_"+toString(outer)+"_"+toString(stage)+"_mesh.e");
            }

          eMesh->copy_field(coord_field_lagged, coord_field);

        }

      //if (!get_parallel_rank()) 

      MPI_Barrier( MPI_COMM_WORLD );

      std::cout << "\nP[" << get_parallel_rank() << "] tmp srk PMMParallelReferenceMeshSmoother: running shape improver... done \n" << std::endl;

      MSQ_ERRRTN(err);
    }
/*!  This function evaluates the needed information and then evaluates
  the termination criteria.  If any of the selected criteria are satisfied,
  the function returns true.  Otherwise, the function returns false.
 */
bool TerminationCriterion::terminate( )
{
  bool return_flag = false;
  //std::cout<<"\nInside terminate(pd,of,err):  flag = "<<terminationCriterionFlag << std::endl;
  int type=0;

    //First check for an interrupt signal
  if (MsqInterrupt::interrupt())
  {
     MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- INTERRUPTED" << " " << std::endl;
    return true;
  }
  
    //if terminating on numbering of inner iterations
  if (NUMBER_OF_ITERATES & terminationCriterionFlag
    && iterationCounter >= iterationBound)
  {
    return_flag = true;
    type=1;
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- Reached " << " " << iterationBound << " iterations." << std::endl;
  }
  
  if (CPU_TIME & terminationCriterionFlag && mTimer.since_birth()>=timeBound)
  {
    return_flag=true;
    type=2;
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- Exceeded CPU time. " << " " << std::endl;
  }
  
  
  if (MOVEMENT_FLAGS & terminationCriterionFlag
      && maxSquaredMovement >= 0.0)
  {
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o Info -- Maximum vertex movement: " << " "
                                   << RPM(sqrt(maxSquaredMovement)) << std::endl;

    if (VERTEX_MOVEMENT_ABSOLUTE & terminationCriterionFlag 
        && maxSquaredMovement <= vertexMovementAbsoluteEps)
    {
      MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- VERTEX_MOVEMENT_ABSOLUTE: " << " "
                                     << RPM(sqrt(maxSquaredMovement)) << std::endl;
      return_flag = true;
    type=3;
    }
  
    if (VERTEX_MOVEMENT_RELATIVE & terminationCriterionFlag
        && maxSquaredMovement <= vertexMovementRelativeEps*maxSquaredInitialMovement)
    {
      MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- VERTEX_MOVEMENT_RELATIVE: " << " "
                                     << RPM(sqrt(maxSquaredMovement)) << std::endl;
      return_flag = true;
    type=4;
    }

    if (VERTEX_MOVEMENT_ABS_EDGE_LENGTH & terminationCriterionFlag)
    {
      assert( vertexMovementAbsoluteAvgEdge > -1e-12 ); // make sure value actually got calculated
      if (maxSquaredMovement <= vertexMovementAbsoluteAvgEdge)
      {
        MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- VERTEX_MOVEMENT_ABS_EDGE_LENGTH: " << " "
                                       << RPM(sqrt(maxSquaredMovement)) << std::endl;
        return_flag = true;
        type=5;
      }
    }
  }

  if (GRADIENT_L2_NORM_ABSOLUTE & terminationCriterionFlag &&
      currentGradL2NormSquared <= gradL2NormAbsoluteEpsSquared)
  {
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- GRADIENT_L2_NORM_ABSOLUTE: " << " " << RPM(currentGradL2NormSquared) << std::endl;
    return_flag = true;
    type=6;
  }
  
  if (GRADIENT_INF_NORM_ABSOLUTE & terminationCriterionFlag &&
      currentGradInfNorm <= gradInfNormAbsoluteEps)
  {
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- GRADIENT_INF_NORM_ABSOLUTE: " << " " << RPM(currentGradInfNorm) << std::endl;
    return_flag = true;
    type=7;
  }
  
  if (GRADIENT_L2_NORM_RELATIVE & terminationCriterionFlag &&
      currentGradL2NormSquared <= (gradL2NormRelativeEpsSquared * initialGradL2NormSquared))
  {
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- GRADIENT_L2_NORM_RELATIVE: " << " " << RPM(currentGradL2NormSquared) << std::endl;
    return_flag = true;
    type=8;
  }
  
  if (GRADIENT_INF_NORM_RELATIVE & terminationCriterionFlag &&
      currentGradInfNorm <= (gradInfNormRelativeEps * initialGradInfNorm))
  {
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- GRADIENT_INF_NORM_RELATIVE: " << " " << RPM(currentGradInfNorm) << std::endl;
    return_flag = true;
    type=9;
  }
    //Quality Improvement and Successive Improvements are below.
    // The relative forms are only valid after the first iteration.
  if ((QUALITY_IMPROVEMENT_ABSOLUTE & terminationCriterionFlag) &&
      currentOFValue <= qualityImprovementAbsoluteEps)
  {
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- QUALITY_IMPROVEMENT_ABSOLUTE: " << " " << RPM(currentOFValue) << std::endl;
    return_flag = true;
    type=10;
  }
  
    //only valid if an iteration has occurred, see above.
  if(iterationCounter > 0){
    if (SUCCESSIVE_IMPROVEMENTS_ABSOLUTE & terminationCriterionFlag &&
        (previousOFValue - currentOFValue) <= successiveImprovementsAbsoluteEps)
    {  
      MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- SUCCESSIVE_IMPROVEMENTS_ABSOLUTE: previousOFValue= " << " " << previousOFValue << " currentOFValue= " << RPM(currentOFValue) 
                             << " successiveImprovementsAbsoluteEps= " << successiveImprovementsAbsoluteEps
                             << std::endl;
      return_flag = true;
    type=11;
    }
    if (QUALITY_IMPROVEMENT_RELATIVE & terminationCriterionFlag &&
        (currentOFValue - lowerOFBound) <= 
        qualityImprovementRelativeEps * (initialOFValue - lowerOFBound))
    {
      MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- QUALITY_IMPROVEMENT_RELATIVE: " << " " << std::endl;
      return_flag = true;
    type=12;
    }
    if (SUCCESSIVE_IMPROVEMENTS_RELATIVE & terminationCriterionFlag &&
        (previousOFValue - currentOFValue) <= 
        successiveImprovementsRelativeEps * (initialOFValue - currentOFValue))
    {
      MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- SUCCESSIVE_IMPROVEMENTS_RELATIVE: previousOFValue= " << " " << previousOFValue << " currentOFValue= " << RPM(currentOFValue) 
                             << " successiveImprovementsRelativeEps= " << successiveImprovementsRelativeEps
                             << std::endl;
      return_flag = true;
    type=13;
    }
  }
  
  if (BOUNDED_VERTEX_MOVEMENT & terminationCriterionFlag && vertexMovementExceedsBound)
  {
    return_flag = true;
    type=14;
    MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- " << " " << vertexMovementExceedsBound
                           << " vertices out of bounds." << std::endl;
  }
  
  if (UNTANGLED_MESH & terminationCriterionFlag)
  {
    if (innerOuterType==TYPE_OUTER) {
      //MSQ_DBGOUT_P0_ONLY(debugLevel) 
      MSQ_DBGOUT(debugLevel) 
        << par_string() << "  o Num Inverted: " << " " << globalInvertedCount << std::endl;
    }
    if (!globalInvertedCount)
      {
        MSQ_DBGOUT_P0_ONLY(debugLevel) << par_string() << "  o TermCrit -- UNTANGLED_MESH: "<< " " << std::endl;
        return_flag = true;
        type=15;
      }
  }
  
    // clear this value at the end of each iteration
  vertexMovementExceedsBound = 0;
  maxSquaredMovement = -1.0;

  if (timeStepFileType == GNUPLOT && return_flag) {
    MsqError err;
    MeshWriter::write_gnuplot_overlay( iterationCounter, timeStepFileName.c_str(), err );
  }

  if (0 && return_flag && MSQ_DBG(2))
    std::cout << "P[" << get_parallel_rank() << "] tmp TerminationCriterion::terminate: " << moniker << " return_flag= " << return_flag << " type= " << type
              << " terminationCriterionFlag= " << terminationCriterionFlag << " debugLevel= " << debugLevel << std::endl;
  
    //if none of the criteria were satisfied
  return return_flag;
}