Esempio n. 1
0
 void test_remove_preconditioner()
 {
    MsqPrintError err(cout);
    mQueue.clear();
    mQueue.add_preconditioner(mQI, err);   // 0
    mQueue.add_quality_assessor(mQA, err); // 1
    mQueue.add_preconditioner(mQI, err);   // 2
    mQueue.set_master_quality_improver(mQI, err);
    CPPUNIT_ASSERT(!err);
    err.clear();
    mQueue.remove_preconditioner(2, err);
    CPPUNIT_ASSERT_MESSAGE("should remove QualityImprover", !err);
    err.clear();
    mQueue.remove_preconditioner(3, err);
    CPPUNIT_ASSERT_MESSAGE("should not remove master QualityImprover", err);
    err.clear();
    mQueue.remove_preconditioner(1, err);
    CPPUNIT_ASSERT_MESSAGE("should not remove QualityAssessor", err);
    err.clear();
    mQueue.remove_preconditioner(0, err);
    CPPUNIT_ASSERT_MESSAGE("should  remove QualityImprover", !err);
    err.clear();
    mQueue.remove_preconditioner(0, err);
    CPPUNIT_ASSERT_MESSAGE("should not remove QualityAssessor", err);   
    err.clear();
 }
Esempio n. 2
0
int main(int argc, char* argv[])
{
  MsqError err;
  
  if (argc != 2) {
    std::cerr << "Expected mesh file names as single argument." << std::endl;
    exit (EXIT_FAILURE);
  }

  // new code starts here
  //... 
  Mesquite::MeshImpl my_mesh;
  my_mesh.read_vtk(argv[1], err);
  if (err)
  {
    std::cout << err << std::endl;
    return 1;
  }

  my_mesh.write_vtk("original_mesh.vtk",err);

  Vector3D normal(0,0,-1);
  Vector3D point(0,0,-5);
  PlanarDomain my_mesh_plane(normal, point);

    // creates a mean ratio quality metric ...
  IdealWeightInverseMeanRatio inverse_mean_ratio(err);
    // sets the objective function template
  LPtoPTemplate obj_func(&inverse_mean_ratio, 2, err);
    // creates the optimization procedures
  SteepestDescent f_newton(&obj_func);
    //performs optimization globally
  f_newton.use_global_patch();
    // creates a termination criterion and
    // add it to the optimization procedure
    // outer loop: default behavior: 1 iteration
    // inner loop: stop if gradient norm < eps
  TerminationCriterion tc_inner;
  tc_inner.add_absolute_gradient_L2_norm( 1e-4 );
  f_newton.set_inner_termination_criterion(&tc_inner);
    // creates a quality assessor
  QualityAssessor m_ratio_qa(&inverse_mean_ratio);
    // creates an instruction queue
  InstructionQueue queue;
  queue.add_quality_assessor(&m_ratio_qa, err);
  queue.set_master_quality_improver(&f_newton, err);
  queue.add_quality_assessor(&m_ratio_qa, err);
    // do optimization of the mesh_set
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&my_mesh, &my_mesh_plane);
  queue.run_instructions(&mesh_and_domain, err);
  if (err) {
    std::cout << err << std::endl;
    return 2;
  }

  my_mesh.write_vtk("smoothed_mesh.vtk",err);

  return 0;
}
Esempio n. 3
0
bool
Loop::optimize()
{
    InstructionQueue invariantInstructions;
    InstructionQueue boundsChecks;

    IonSpew(IonSpew_LICM, "These instructions are in the loop: ");

    while (!worklist_.empty()) {
        if (mir->shouldCancel("LICM (worklist)"))
            return false;

        MInstruction *ins = popFromWorklist();

        IonSpewHeader(IonSpew_LICM);

        if (IonSpewEnabled(IonSpew_LICM)) {
            ins->printName(IonSpewFile);
            fprintf(IonSpewFile, " <- ");
            ins->printOpcode(IonSpewFile);
            fprintf(IonSpewFile, ":  ");
        }

        if (isLoopInvariant(ins)) {
            // Flag this instruction as loop invariant.
            ins->setLoopInvariant();
            if (!invariantInstructions.append(ins))
                return false;

            // Loop through uses of invariant instruction and add back to work list.
            for (MUseDefIterator iter(ins->toDefinition()); iter; iter++) {
                MDefinition *consumer = iter.def();

                if (consumer->isInWorklist())
                    continue;

                // if the consumer of this invariant instruction is in the
                // loop, and it is also worth hoisting, then process it.
                if (isInLoop(consumer) && isHoistable(consumer)) {
                    if (!insertInWorklist(consumer->toInstruction()))
                        return false;
                }
            }

            if (IonSpewEnabled(IonSpew_LICM))
                fprintf(IonSpewFile, " Loop Invariant!\n");
        } else if (ins->isBoundsCheck()) {
            if (!boundsChecks.append(ins))
                return false;
        }
    }

    if (!hoistInstructions(invariantInstructions, boundsChecks))
        return false;
    return true;
}
Esempio n. 4
0
int main( int argc, char* argv[] )
{
  parse_options( argv, argc );
  
  MeshImpl mesh;
  XYRectangle domain( max_x - min_x, max_y - min_y, min_x, min_y );
  MsqError err;
  
  create_input_mesh( input_x, mesh, err );
  if (MSQ_CHKERR(err)) { std::cerr << err << std::endl; return 2; }
  
  domain.setup( &mesh, err );
  if (MSQ_CHKERR(err)) { std::cerr << err << std::endl; return 2; }
  
  QualityMetric* metric = 0;
  if (mMetric == 'c')
    metric = new ConditionNumberQualityMetric;
  else
    metric = new IdealWeightInverseMeanRatio;
  
  LPtoPTemplate function( 1, metric );
  
  VertexMover* solver = 0;
  if (mSolver == 'j')
    solver = new ConjugateGradient( &function );
  else
    solver = new FeasibleNewton( &function );
    
  if (PatchSetUser* psu = dynamic_cast<PatchSetUser*>(solver)) 
    psu->use_global_patch();
  
  TerminationCriterion inner;
  inner.add_absolute_vertex_movement( 1e-4 );
  inner.write_mesh_steps( "synchronous", TerminationCriterion::GNUPLOT );
  solver->set_inner_termination_criterion( &inner );  
  
  InstructionQueue q;
  QualityAssessor qa( metric, 10 );
  q.add_quality_assessor( &qa, err );
  q.set_master_quality_improver( solver, err );
  q.add_quality_assessor( &qa, err );
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &domain);
  q.run_instructions( &mesh_and_domain, err );
  delete solver;
  delete metric;
  
  if (MSQ_CHKERR(err)) 
    { std::cerr << err << std::endl; return 3; }
    
  mesh.write_vtk( outputFile, err );
  if (MSQ_CHKERR(err)) 
    { std::cerr << err << std::endl; return 2; }
  
  return 0;
}
Esempio n. 5
0
  void test_add_quality_assessor()
 {
    MsqPrintError err(cout);
    mQueue.clear();
    mQueue.add_quality_assessor(mQA, err);
    CPPUNIT_ASSERT(!err);
    err.clear();
    mQueue.set_master_quality_improver(mQI,err);
    CPPUNIT_ASSERT(!err);
    err.clear();
    mQueue.add_quality_assessor(mQA, err);
    CPPUNIT_ASSERT(!err);
 }
Esempio n. 6
0
 void test_add_preconditioner()
 {
    MsqPrintError err(cout);
    mQueue.clear();
    mQueue.add_preconditioner(mQI, err);
    CPPUNIT_ASSERT(!err);
    err.clear();
    mQueue.set_master_quality_improver(mQI,err);
    CPPUNIT_ASSERT(!err);
    err.clear();
    mQueue.add_preconditioner(mQI, err);
    CPPUNIT_ASSERT_MESSAGE("preconditioner cannot be added after master QI"
                           , err);
    err.clear(); 
 }
Esempio n. 7
0
bool InstructionQueue::diffPossible(InstructionQueue &model, float required)
{
	required *= model.size();
	statCheck();
	model.statCheck();

	int possible = model.size();
	for (auto &pair : model._stat) {
		possible -= _stat.count(pair.first) ? pair.second - min(pair.second, _stat[pair.first]) : pair.second;
		if (possible < required)
			return false;
	}

	return true;
}
Esempio n. 8
0
void TagVertexMeshTest::test_reference_mesh()
{
  MsqPrintError err( std::cerr );
  TagVertexMesh tag_mesh( err, realMesh, true );
  ASSERT_NO_ERROR(err);
  
  std::vector<Mesh::VertexHandle> vertices;
  realMesh->get_all_vertices( vertices, err );
  ASSERT_NO_ERROR(err);
  
    // copy real mesh coordinates into tag data in TagVertexMesh
  InstructionQueue q;
  q.add_tag_vertex_mesh( &tag_mesh, err );
  ASSERT_NO_ERROR(err);
  q.run_instructions( realMesh, err );
  ASSERT_NO_ERROR(err);
  
    // Check that initial position for vertex matches that of real mesh
  Mesh::VertexHandle vertex = vertices[0];
  MsqVertex get_coords;
  Vector3D orig_coords, real_coords, tag_coords;
  realMesh->vertices_get_coordinates( &vertex, &get_coords, 1, err );
  ASSERT_NO_ERROR(err);
  orig_coords = get_coords;
  tag_mesh.vertices_get_coordinates( &vertex, &get_coords, 1, err );
  ASSERT_NO_ERROR(err);
  tag_coords = get_coords;
  CPPUNIT_ASSERT_VECTORS_EQUAL( orig_coords, tag_coords, DBL_EPSILON );
  
    // Check that modified vertex coords show up in real mesh but not
    // tag mesh.
  realMesh->vertices_get_coordinates( &vertex, &get_coords, 1, err );
  ASSERT_NO_ERROR(err);
  orig_coords = get_coords;
  Vector3D new_coords(5,5,5);
  realMesh->vertex_set_coordinates( vertex, new_coords, err );
  ASSERT_NO_ERROR(err);
  tag_mesh.vertices_get_coordinates( &vertex, &get_coords, 1, err );
  ASSERT_NO_ERROR(err);
  tag_coords = get_coords;
  CPPUNIT_ASSERT_VECTORS_EQUAL( orig_coords, tag_coords, DBL_EPSILON );
    // restore realMesh to initial state
  realMesh->vertex_set_coordinates( vertex, orig_coords, err );
  ASSERT_NO_ERROR(err);
}
Esempio n. 9
0
bool
Loop::hoistInstructions(InstructionQueue &toHoist)
{
    // Iterate in post-order (uses before definitions)
    for (int32_t i = toHoist.length() - 1; i >= 0; i--) {
        MInstruction *ins = toHoist[i];

        // Don't hoist MConstantElements, MConstant and MBox
        // if it doesn't enable us to hoist one of its uses.
        // We want those instructions as close as possible to their use.
        if (ins->isConstantElements() || ins->isConstant() || ins->isBox()) {
            bool loopInvariantUse = false;
            for (MUseDefIterator use(ins); use; use++) {
                if (use.def()->isLoopInvariant()) {
                    loopInvariantUse = true;
                    break;
                }
            }

            if (!loopInvariantUse)
                ins->setNotLoopInvariant();
        }
    }

    // Move all instructions to the preLoop_ block just before the control instruction.
    for (size_t i = 0; i < toHoist.length(); i++) {
        MInstruction *ins = toHoist[i];

        // Loads may have an implicit dependency on either stores (effectful instructions) or
        // control instructions so we should never move these.
        JS_ASSERT(!ins->isControlInstruction());
        JS_ASSERT(!ins->isEffectful());
        JS_ASSERT(ins->isMovable());

        if (!ins->isLoopInvariant())
            continue;

        if (checkHotness(ins->block())) {
            ins->block()->moveBefore(preLoop_->lastIns(), ins);
            ins->setNotLoopInvariant();
        }
    }

    return true;
}
Esempio n. 10
0
void PaverMinEdgeLengthWrapper::run_wrapper( Mesh* mesh,
                                             ParallelMesh* pmesh,
                                             MeshDomain* domain,
                                             Settings* settings,
                                             QualityAssessor* qa,
                                             MsqError& err )
{
  InstructionQueue q;
 
    // calculate average lambda for mesh
  ReferenceMesh ref_mesh( mesh );
  RefMeshTargetCalculator W_0( &ref_mesh );
  SimpleStats lambda_stats;
  MeshUtil tool(mesh, settings);
  tool.lambda_distribution( lambda_stats, err ); MSQ_ERRRTN(err);
  double lambda = lambda_stats.average();
  
    // create objective function
  IdealShapeTarget W_i;
  LambdaConstant W( lambda, &W_i );
  TShapeSizeB1 tm;
  TQualityMetric mu_0( &W, &tm );
  ElementPMeanP mu( 1.0, &mu_0 );
  PMeanPTemplate of( 1.0, &mu );
  
    // create quality assessor
  EdgeLengthMetric len(0.0);
  qa->add_quality_assessment( &mu );
  qa->add_quality_assessment( &len );
  q.add_quality_assessor( qa, err );
  
    // create solver
  TrustRegion solver( &of );
  TerminationCriterion tc, ptc;
  tc.add_absolute_vertex_movement( maxVtxMovement );
  tc.add_iteration_limit( iterationLimit );
  ptc.add_iteration_limit( pmesh ? parallelIterations : 1 );
  solver.set_inner_termination_criterion( &tc );
  solver.set_outer_termination_criterion( &ptc );
  q.set_master_quality_improver( &solver, err ); MSQ_ERRRTN(err);
  q.add_quality_assessor( qa, err );

  // Optimize mesh
  q.run_common( mesh, pmesh, domain, settings, err ); MSQ_CHKERR(err);  
}
Esempio n. 11
0
int ParShapeImprover::count_invalid_elements(Mesh &mesh, MeshDomain *domain)
{
  MsqError err;
  InstructionQueue q;
  
  IdealWeightInverseMeanRatio metric;
  metric.set_averaging_method( QualityMetric::LINEAR );

  // Check for inverted elements in the mesh
  QualityAssessor inv_check( &metric );
  //inv_check.disable_printing_results();
  q.add_quality_assessor( &inv_check, err );  MSQ_ERRZERO(err);
  Settings settings;
  // bug?  should we pass in pmesh?
  q.run_common( &mesh, 0, domain, &settings, err ); MSQ_ERRZERO(err);
  const QualityAssessor::Assessor* inv_b = inv_check.get_results( &metric );
  int num_invalid = inv_b->get_invalid_element_count();
  return num_invalid;
}
Esempio n. 12
0
bool
Loop::optimize()
{
    InstructionQueue invariantInstructions;

    IonSpew(IonSpew_LICM, "These instructions are in the loop: ");

    while (!worklist_.empty()) {
        if (mir->shouldCancel("LICM (worklist)"))
            return false;

        MInstruction *ins = popFromWorklist();

        IonSpewHeader(IonSpew_LICM);

        if (IonSpewEnabled(IonSpew_LICM)) {
            ins->printName(IonSpewFile);
            fprintf(IonSpewFile, " <- ");
            ins->printOpcode(IonSpewFile);
            fprintf(IonSpewFile, ":  ");
        }

        if (isLoopInvariant(ins)) {
            // Flag this instruction as loop invariant.
            ins->setLoopInvariant();
            if (!invariantInstructions.append(ins))
                return false;

            if (IonSpewEnabled(IonSpew_LICM))
                fprintf(IonSpewFile, " Loop Invariant!\n");
        }
    }

    if (!hoistInstructions(invariantInstructions))
        return false;
    return true;
}
Esempio n. 13
0
void MeshOpt::trustRegion(hier::Patch<NDIM>& patch)
{
    MsqError err;
    MeshImpl* mesh = createLocalMesh(patch);

    PlanarDomain domain(PlanarDomain::XY);
    IdealWeightInverseMeanRatio inverse_mean_ratio(err);
    LPtoPTemplate obj_func(&inverse_mean_ratio,2,err);
    TrustRegion t_region(&obj_func);
    t_region.use_global_patch();
    TerminationCriterion tc_inner;
    tc_inner.add_absolute_gradient_L2_norm(1e-6);
    tc_inner.add_iteration_limit(1);
    t_region.set_inner_termination_criterion(&tc_inner);
    QualityAssessor m_ratio_qa(&inverse_mean_ratio);
    m_ratio_qa.disable_printing_results();

    InstructionQueue queue;
    queue.add_quality_assessor(&m_ratio_qa,err);
    queue.set_master_quality_improver(&t_region,err);
    queue.add_quality_assessor(&m_ratio_qa,err);
    MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(mesh,&domain);
    queue.run_instructions(&mesh_and_domain,err);
    tbox::pout<< "Shape optimization completed." << std::endl;

//    std::string file_name = "2__patch_3.vtk";
//    mesh->write_vtk(file_name.c_str(), err);

    transformMeshtoPatch(mesh,patch,err);



    d_flag =2;

    return;
}
Esempio n. 14
0
 void test_insert_preconditioner()
 {
    MsqPrintError err(cout);
    mQueue.clear();
    mQueue.add_preconditioner(mQI, err);   // 0
    mQueue.add_quality_assessor(mQA, err); // 1
    mQueue.add_preconditioner(mQI, err);   // 2
    mQueue.set_master_quality_improver(mQI, err);
    CPPUNIT_ASSERT(!err);
    err.clear();
    mQueue.insert_preconditioner(mQI,2, err);
    CPPUNIT_ASSERT(!err);
    err.clear();
    mQueue.insert_preconditioner(mQI, 5, err);
    CPPUNIT_ASSERT_MESSAGE("should not insert after master QualityImprover", err);
    err.clear();
 }
Esempio n. 15
0
 void test_insert_quality_assessor()
 {
    MsqPrintError err(cout);
    mQueue.clear();
    mQueue.add_preconditioner(mQI, err);   // 0
    mQueue.add_quality_assessor(mQA, err); // 1
    mQueue.add_preconditioner(mQI, err);   // 2
    mQueue.set_master_quality_improver(mQI, err);
    CPPUNIT_ASSERT(!err);
    err.clear();
    mQueue.insert_quality_assessor(mQA,2, err);
    CPPUNIT_ASSERT(!err);
    err.clear();
    mQueue.insert_quality_assessor(mQA, 5, err);
    CPPUNIT_ASSERT(!err);
    err.clear();
 }
void SizeAdaptShapeWrapper::run_wrapper( Mesh* mesh, 
                                         ParallelMesh* pmesh,
                                         MeshDomain* domain, 
                                         Settings* settings,
                                         QualityAssessor* qa,
                                         MsqError& err )
{
  InstructionQueue q;
 
    // calculate average lambda for mesh
  TagVertexMesh init_mesh( err, mesh );  MSQ_ERRRTN(err);
  ReferenceMesh ref_mesh( &init_mesh );
  RefMeshTargetCalculator W_0( &ref_mesh );
  q.add_tag_vertex_mesh( &init_mesh, err );  MSQ_ERRRTN(err);
  
    // create objective function
  IdealShapeTarget W_i;
  LambdaTarget W( &W_0, &W_i );
  Target2DShapeSizeBarrier tm2;
  Target3DShapeSizeBarrier tm3;
  TMPQualityMetric mu( &W, &tm2, &tm3 );
  PMeanPTemplate of( 1.0, &mu );
  
    // create quality assessor
  EdgeLengthMetric len(0.0);
  qa->add_quality_assessment( &mu );
  qa->add_quality_assessment( &len );
  q.add_quality_assessor( qa, err );
  
    // create solver
  TrustRegion solver( &of );
  TerminationCriterion tc, ptc;
  tc.add_absolute_vertex_movement( maxVtxMovement );
  tc.add_iteration_limit( iterationLimit );
  ptc.add_iteration_limit( pmesh ? parallelIterations : 1 );
  solver.set_inner_termination_criterion( &tc );
  solver.set_outer_termination_criterion( &ptc );
  q.set_master_quality_improver( &solver, err ); MSQ_ERRRTN(err);
  q.add_quality_assessor( qa, err );

  // Optimize mesh
  q.run_common( mesh, pmesh, domain, settings, err ); MSQ_CHKERR(err);  
}
Esempio n. 17
0
int main(int argc, char* argv[])
{
  const char* initial_mesh_file = 0;
  const char* final_mesh_file = 0;
  for (int i = 1; i < argc; ++i) {
    if (!strcmp(argv[i],"-f")) {
      ++i;
      if (i == argc)
        usage(argv[0]);
      final_mesh_file = argv[i];
    }
    else if (!strcmp(argv[i],"-i")) {
      ++i;
      if (i == argc)
        usage(argv[0]);
      initial_mesh_file = argv[i];
    }
    else
      usage( argv[i] );
  }


    // create mesh
  const int intervals = 3;
  const double perturb = 0.3;
  const int nvtx = (intervals+1) * (intervals+1);
  double coords[nvtx*3];
  double exp_coords[nvtx*3];
  int fixed[nvtx];
  for (int i = 0; i < nvtx; ++i) {
    double* c = coords + 3*i;
    double* e = exp_coords + 3*i;
    int row = i / (intervals+1);
    int col = i % (intervals+1);
    double xdelta, ydelta;
    if (row > 0 && row < intervals && col > 0 && col < intervals) {
      fixed[i] = 0;
      xdelta = row % 2 ? -perturb : 0;
      ydelta = col % 2 ? perturb : -perturb;
    }
    else {
      fixed[i] = 1;
      xdelta = ydelta = 0.0;
    }
    c[0] = col + xdelta;
    c[1] = row + ydelta;
    c[2] = 0.0;
    e[0] = col;
    e[1] = row;
    e[2] = 0.0;
  }
  const int nquad = intervals * intervals;
  unsigned long conn[nquad * 4];
  for (int i = 0; i < nquad; ++i) {
    unsigned long* c = conn + 4*i;
    int row = i / intervals;
    int col = i % intervals;
    int n0 = (intervals+1)*row + col;
    c[0] = n0;
    c[1] = n0+1;
    c[2] = n0+intervals+2;
    c[3] = n0+intervals+1;
  }
  MsqPrintError err(std::cerr);
  ArrayMesh mesh( 3, nvtx, coords, fixed, nquad, QUADRILATERAL, conn );
  PlanarDomain zplane( PlanarDomain::XY );
  if (initial_mesh_file) {
    MeshWriter::write_vtk( &mesh, initial_mesh_file, err );
    if (err) {
      fprintf(stderr,"%s: failed to write file\n", initial_mesh_file );
      return 1;
    }
  }
  
    // do optimization
  const double eps = 0.01;
  IdealShapeTarget w;
  TShapeB1 mu;
  TQualityMetric metric( &w, &mu );
  PMeanPTemplate func( 1.0, &metric );
  SteepestDescent solver( &func );
  solver.use_element_on_vertex_patch();
  solver.do_jacobi_optimization();
  TerminationCriterion inner, outer;
  inner.add_absolute_vertex_movement( 0.5*eps );
  outer.add_absolute_vertex_movement( 0.5*eps );
  QualityAssessor qa( &metric );
  InstructionQueue q;
  q.add_quality_assessor( &qa, err );
  q.set_master_quality_improver( &solver, err );
  q.add_quality_assessor( &qa, err );
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &zplane);
  q.run_instructions( &mesh_and_domain, err );
  if (err)
    return 2;
  if (final_mesh_file) {
    MeshWriter::write_vtk( &mesh, final_mesh_file, err );
    if (err) {
      fprintf(stderr,"%s: failed to write file\n", final_mesh_file );
      return 1;
    }
  }
  
    // check final vertex positions
  int invalid = 0;
  for (int i = 0; i < nvtx; ++i) {
    if (dist( coords + 3*i, exp_coords + 3*i ) > eps) {
      ++invalid;
      printf("Vertex %d at (%f,%f,%f), expected at (%f,%f,%f)\n", i,
        coords[3*i], coords[3*i+1], coords[3*i+2],
        exp_coords[3*i], exp_coords[3*i+1], exp_coords[3*i+2] );
    }
  }
  
  return invalid ? 2 : 0;
}
Esempio n. 18
0
double run( QualityMetric* metric, 
            Solver solver_type,
            const char* input_file,
            double& seconds_out,
            int& iterations_out )
{
  MsqPrintError err(cerr);
  IdealWeightInverseMeanRatio qa_metric;
  TerminationCriterion inner, outer;
  outer.add_iteration_limit( 1 );
  inner.add_absolute_vertex_movement( 1e-4 );
  inner.add_iteration_limit( 100 );
  PMeanPTemplate of( 1.0, metric );
  QualityAssessor qa( &qa_metric );
  qa.add_quality_assessment( metric );
  InstructionQueue q;
  SteepestDescent steep(&of);
  QuasiNewton quasi(&of);
  ConjugateGradient conj(&of);
  VertexMover* solver = 0;
  switch (solver_type) {
    case STEEP_DESCENT: solver = &steep; break;
    case QUASI_NEWT:solver = &quasi;break;
    case CONJ_GRAD: solver = &conj; break;
  }
  q.set_master_quality_improver( solver, err );
  q.add_quality_assessor( &qa, err );
  solver->set_inner_termination_criterion(&inner);
  solver->set_outer_termination_criterion(&outer);
  
  
  if (plot_file)
    inner.write_iterations( plot_file, err );
  
  MeshImpl mesh;
  mesh.read_vtk( input_file, err );
  if (err) {
    cerr << "Failed to read input file: \"" << input_file << '"' << endl;
    exit(1);
  }
  
  std::vector<Mesh::VertexHandle> handles;
  mesh.get_all_vertices( handles, err );
  if (handles.empty()) {
    cerr << "no veritces in mesh" << endl;
    exit(1);
  }
  std::vector<MsqVertex> coords(handles.size());
  mesh.vertices_get_coordinates( arrptr(handles), arrptr(coords), handles.size(), err );
  Vector3D min(HUGE_VAL), max(-HUGE_VAL);
  for (size_t i = 0; i < coords.size(); ++i) {
    for (int j = 0; j < 3; ++j) {
      if (coords[i][j] < min[j])
        min[j] = coords[i][j];
      if (coords[i][j] > max[j])
        max[j] = coords[i][j];
    }
  }
  
  Vector3D size = max - min;
  PlanarDomain* domain = 0;
  if (size[0] < 1e-4) 
    domain = new PlanarDomain( PlanarDomain::YZ, min[0] );
  else if (size[1] < 1e-4)
    domain = new PlanarDomain( PlanarDomain::XZ, min[1] );
  else if (size[2] < 1e-4)
    domain = new PlanarDomain( PlanarDomain::XY, min[2] );
  
  Timer timer;
  q.run_instructions( &mesh, domain, err );
  seconds_out = timer.since_birth();
  if (err) {
    cerr << "Optimization failed." << endl << err << endl;
    abort();
  }

  if (vtk_file) {
    MeshWriter::write_vtk( &mesh, vtk_file, err );
    if (err) 
      cerr << vtk_file << ": failed to write file." << endl;
  }
  if (gpt_file) {
    MeshWriter::write_gnuplot( &mesh, gpt_file, err );
    if (err) 
      cerr << gpt_file << ": failed to write file." << endl;
  }
  if (eps_file) {
    PlanarDomain xy(PlanarDomain::XY);
    MeshWriter::Projection proj( domain ? domain : &xy );
    MeshWriter::write_eps( &mesh, eps_file, proj, err );
    if (err) 
      cerr << eps_file << ": failed to write file." << endl;
  }
  delete domain;
  
  iterations_out = inner.get_iteration_count();
  
  const QualityAssessor::Assessor* a = qa.get_results( &qa_metric );
  return a->get_average();
}
Esempio n. 19
0
int main( int argc, char* argv[] )
{
  const char* input_file = DEFAULT_INPUT_FILE;
  const char* output_file_base = 0;
  bool expect_output_base = false;
  for (int i = 1; i < argc; ++i) {
    if (expect_output_base) {
      output_file_base = argv[i];
      expect_output_base = false;
    }
    else if (!strcmp(argv[i],"-o"))
      expect_output_base = true;
    else if (input_file != DEFAULT_INPUT_FILE)
      usage(argv[0]);
    else
      input_file = argv[i];
  }
  if (expect_output_base)
    usage(argv[0]);
  
  MsqPrintError err(std::cerr);
  SlaveBoundaryVertices slaver(1);
  TShapeNB1 tmetric;
  IdealShapeTarget target;
  TQualityMetric metric( &target, &tmetric );
  PMeanPTemplate of( 1.0, &metric );
  SteepestDescent improver( &of );
  TerminationCriterion inner;
  inner.add_absolute_vertex_movement( 1e-3 );
  improver.set_inner_termination_criterion( &inner );
  QualityAssessor assess( &metric );
  InstructionQueue q;
  q.set_master_quality_improver( &improver, err );
  q.add_quality_assessor( &assess, err );
  
  TriLagrangeShape trishape;
  QuadLagrangeShape quadshape;
  q.set_mapping_function( &trishape );
  q.set_mapping_function( &quadshape );
  
  const int NUM_MODES = 4;
  
  Settings::HigherOrderSlaveMode modes[NUM_MODES] = 
    { Settings::SLAVE_NONE, 
      Settings::SLAVE_ALL,
      Settings::SLAVE_CALCULATED,
      Settings::SLAVE_FLAG
    };
  
  std::string names[NUM_MODES] = 
    { "NONE",
      "ALL",
      "CALCULATED",
      "FLAG" };
  
  MeshImpl meshes[NUM_MODES];
  std::vector<MeshDomainAssoc> meshes_and_domains;

  bool have_slaved_flag = true;
  std::vector<bool> flag(1);
  for (int i = 0; i < NUM_MODES; ++i) {
    std::cout << std::endl
              << "-----------------------------------------------" << std::endl
              << "     Mode: " << names[i] << std::endl
              << "-----------------------------------------------" << std::endl;
    
    meshes[i].read_vtk( input_file, err );
    if (err) return 1;
  
    if (modes[i] == Settings::SLAVE_CALCULATED) {
        q.add_vertex_slaver( &slaver, err );
    }
    else if (modes[i] == Settings::SLAVE_FLAG) {
      std::vector<Mesh::VertexHandle> verts;
      meshes[i].get_all_vertices( verts, err );
      if (err) return 1;
      meshes[i].vertices_get_slaved_flag( arrptr(verts), flag, 1, err );
      if (err) {
        have_slaved_flag = false;
        std::cout << "Skipped because input file does not contain slaved attribute" << std::endl;
        err.clear();
        continue;
      }
    }

  
    if (have_slaved_flag && modes[i] == Settings::SLAVE_FLAG) {
      if (!check_no_slaved_corners( meshes[i], err ) || err)
        return 1;
      if (!check_global_patch_slaved( meshes[i], err ) || err)
        return 1;
    }

  
    PlanarDomain plane;
    plane.fit_vertices( &meshes[i], err );
    if (err) return 1;

    q.set_slaved_ho_node_mode( modes[i] );
    meshes_and_domains.push_back(MeshDomainAssoc(&meshes[i], &plane));
    q.run_instructions( &meshes_and_domains[i], err );
    if (err) return 1;

    if (modes[i] == Settings::SLAVE_CALCULATED) {
        q.remove_vertex_slaver( &slaver, err );
    }
    
    if (output_file_base) {
      tag_patch_slaved( meshes[i], modes[i], err );
      std::string name(output_file_base);
      name += "-";
      name += names[i];
      name += ".vtk";
      meshes[i].write_vtk( name.c_str(), err );
      if (err) return 1;
    }
  }
  
  int exit_code = 0;
  if (input_file == DEFAULT_INPUT_FILE) {
    for (int i = 0; i < NUM_MODES; ++i) {
      std::cout << std::endl
                << "-----------------------------------------------" << std::endl
                << "     Mode: " << names[i] << std::endl
                << "-----------------------------------------------" << std::endl;
    
      exit_code += check_slaved_coords( meshes[i], modes[i], names[i], have_slaved_flag, err );
      if (err) return 1;
    }
    
      // flags should correspond to same slaved nodes as calculated,
      // so resulting meshes should be identical.
    if (have_slaved_flag) {
      int flag_idx = std::find( modes, modes+NUM_MODES, Settings::SLAVE_FLAG ) - modes;
      int calc_idx = std::find( modes, modes+NUM_MODES, Settings::SLAVE_CALCULATED ) - modes;
      exit_code += compare_node_coords( meshes[flag_idx], meshes[calc_idx], err );
      if (err) return 1;    
    }
  }
  
  return exit_code;
}
void TerminationCriterionTest::test_abs_vtx_movement_culling()
{
  /* define a quad mesh like the following
    16--17--18--19--20--21--22--23
     |   |   |   |   |   |   |   |   Y
     8---9--10--11--12--13--14--15   ^
     |   |   |   |   |   |   |   |   |
     0---1---2---3---4---5---6---7   +-->X
  */

  const int nvtx = 24;
  int fixed[nvtx];
  double coords[3*nvtx];
  for (int i = 0; i < nvtx; ++i) {
    coords[3*i  ] = i/8;
    coords[3*i+1] = i%8;
    coords[3*i+2] = 0;
    fixed[i] = i < 9 || i > 14;
  }
  
  const int nquad = 14;
  unsigned long conn[4*nquad];
  for (int i= 0; i < nquad; ++i) {
    int row = i / 7;
    int idx = i % 7;
    int n0 = 8*row + idx;
    conn[4*i  ] = n0;
    conn[4*i+1] = n0 + 1;
    conn[4*i+2] = n0 + 9;
    conn[4*i+3] = n0 + 8;
  }
  
  const double tol = 0.05;
  PlanarDomain zplane(PlanarDomain::XY, 0.0);
  ArrayMesh mesh( 3, nvtx, coords, fixed, nquad, QUADRILATERAL, conn );
  
    // fill vertex byte with garbage to make sure that quality improver
    // is initializing correctly.
  MsqError err;
  std::vector<unsigned char> junk(nvtx, 255);
  std::vector<Mesh::VertexHandle> vertices;
  mesh.get_all_vertices( vertices, err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_EQUAL( junk.size(), vertices.size() );
  mesh.vertices_set_byte( &vertices[0], &junk[0], vertices.size(), err );
  ASSERT_NO_ERROR(err);  
  
    // Define optimizer
  TCTFauxOptimizer smoother( 2*tol );
  TerminationCriterion outer, inner;
  outer.add_absolute_vertex_movement( tol );
  inner.cull_on_absolute_vertex_movement( tol );
  inner.add_iteration_limit( 1 );
  smoother.set_inner_termination_criterion( &inner );
  smoother.set_outer_termination_criterion( &outer );
  
    // No run the "optimizer"
  InstructionQueue q;
  q.set_master_quality_improver( &smoother, err );
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &zplane);
  q.run_instructions( &mesh_and_domain, err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT( smoother.should_have_terminated() );
  CPPUNIT_ASSERT( smoother.num_passes() > 1 );
}
Esempio n. 21
0
static int do_smoother( const char* input_file, 
                        const char* output_file, 
                        const char* ref_mesh_file,
                        double of_power, 
                        unsigned metric_idx,
                        AveragingScheme avg_scheme )
{
  MsqPrintError err(cerr);
  
  TMetric *const target_metric = metrics[metric_idx].u;
  cout << "Input file:  " << input_file << endl;
  cout << "Metric:      ";
  if (avg_scheme != NONE)
    cout << averaging_names[avg_scheme] << " average of ";
  cout << metrics[metric_idx].n << endl;
  cout << "Of Power:    " << of_power << endl;
  
  
  auto_ptr<TargetCalculator> tc;
  auto_ptr<MeshImpl> ref_mesh_impl;
  auto_ptr<ReferenceMesh> ref_mesh;
  if (ref_mesh_file) {
    ref_mesh_impl.reset(new MeshImpl);
    ref_mesh_impl->read_vtk( ref_mesh_file, err );
    if (MSQ_CHKERR(err)) return 2;
    ref_mesh.reset( new ReferenceMesh( ref_mesh_impl.get() ));
    tc.reset( new RefMeshTargetCalculator( ref_mesh.get() ) );
  }
  else {
    tc.reset( new IdealShapeTarget( ) );
  }
    
  TQualityMetric jacobian_metric( tc.get(), target_metric );
  ElementPMeanP elem_avg( of_power, &jacobian_metric );
  VertexPMeanP vtx_avg( of_power, &jacobian_metric );
  QualityMetric* mmetrics[] = { &jacobian_metric, &elem_avg, &vtx_avg, &jacobian_metric };
  QualityMetric* metric = mmetrics[avg_scheme];

  TerminationCriterion outer, inner;
  outer.add_iteration_limit( 1 );
  inner.add_absolute_vertex_movement( 1e-4 );
  inner.add_iteration_limit( 100 );
  
  PMeanPTemplate obj1( of_power, metric );
  PatchPowerMeanP obj2( of_power, metric );
  ObjectiveFunction& objective = *((avg_scheme == PATCH) ? (ObjectiveFunction*)&obj2 : (ObjectiveFunction*)&obj1);
  
  ConjugateGradient solver( &objective, err );
  if (MSQ_CHKERR(err)) return 1;
  solver.set_inner_termination_criterion( &inner );
  solver.set_outer_termination_criterion( &outer );
  solver.use_global_patch();
  
  ConditionNumberQualityMetric qm_metric;
  QualityAssessor before_assessor;
  QualityAssessor after_assessor;
  before_assessor.add_quality_assessment( metric, 10);
  before_assessor.add_quality_assessment( &qm_metric );
  after_assessor.add_quality_assessment( metric, 10 );

  InstructionQueue q;
  q.add_quality_assessor( &before_assessor, err );
  q.set_master_quality_improver( &solver, err );
  q.add_quality_assessor( &after_assessor, err );
  
  MeshImpl mesh;
  mesh.read_vtk( input_file, err );
  if (MSQ_CHKERR(err)) return 2;
  PlanarDomain geom = make_domain( &mesh, err );
  if (MSQ_CHKERR(err)) return 1;
  q.run_instructions( &mesh, &geom, err );
  if (MSQ_CHKERR(err)) return 3;
  mesh.write_vtk( output_file, err );
  if (MSQ_CHKERR(err)) return 2;
  cout << "Wrote: " << output_file << endl;

  before_assessor.scale_histograms(&after_assessor);
  
  return 0;
}
Esempio n. 22
0
bool smooth_mixed_mesh( const char* filename )
{
  Mesquite::MsqPrintError err(cout);
  
  // print a little output so we know when we died
  std::cout << 
  "**************************************************************************" 
  << std::endl << 
  "* Smoothing: " << filename
  << std::endl  <<
  "**************************************************************************" 
  << std::endl;
  
  // The instruction queue to set up
  InstructionQueue Q;
  
  // Use numeric approx of derivitives until analytic solutions
  // are working for pyramids
  IdealWeightInverseMeanRatio mr_metric(err);
  //sRI_DFT dft_metric;
  UntangleBetaQualityMetric un_metric(0);
  CPPUNIT_ASSERT(!err);
  
    // Create Mesh object
  Mesquite::MeshImpl mesh;
  mesh.read_vtk(filename, err);
  CPPUNIT_ASSERT(!err);

  // Set up a preconditioner
  LInfTemplate pre_obj_func( &un_metric );
  ConjugateGradient precond( &pre_obj_func, err ); CPPUNIT_ASSERT(!err);
  precond.use_element_on_vertex_patch();
  TerminationCriterion pre_term, pre_outer;
  //pre_term.add_relative_quality_improvement( 0.1 );
  pre_term .add_iteration_limit( 3 );
  pre_outer.add_iteration_limit( 1 );
  CPPUNIT_ASSERT(!err);
  precond.set_inner_termination_criterion( &pre_term );
  precond.set_outer_termination_criterion( &pre_outer );
  //precond.use_element_on_vertex_patch();

  // Set up objective function
  LPtoPTemplate obj_func(&mr_metric, 1, err);
  CPPUNIT_ASSERT(!err);

  // Create solver
  FeasibleNewton solver( &obj_func, true );
  CPPUNIT_ASSERT(!err);
  solver.use_global_patch();
  CPPUNIT_ASSERT(!err);

  // Set stoping criteria for solver
  TerminationCriterion tc_inner;
  tc_inner.add_relative_quality_improvement( 0.25 );
  solver.set_inner_termination_criterion(&tc_inner);
   
  TerminationCriterion tc_outer;
  tc_outer.add_iteration_limit( 1 );
  CPPUNIT_ASSERT(!err);
  solver.set_outer_termination_criterion(&tc_outer);

  // Create a QualityAssessor
  Mesquite::QualityAssessor qa;
  qa.add_quality_assessment( &mr_metric );
  qa.add_quality_assessment( &un_metric );
  Q.add_quality_assessor( &qa, err ); 
  CPPUNIT_ASSERT(!err);
 
  // Add untangler to queue
  Q.add_preconditioner( &precond, err ); CPPUNIT_ASSERT(!err);
  Q.add_quality_assessor( &qa, err ); 
  CPPUNIT_ASSERT(!err);
 
  // Add solver to queue
  Q.set_master_quality_improver(&solver, err); 
  CPPUNIT_ASSERT(!err);
  Q.add_quality_assessor( &qa, err ); 
  CPPUNIT_ASSERT(!err);
 
  // And smooth...
  Q.run_instructions(&mesh, err); 
  CPPUNIT_ASSERT(!err);

  return false;
}
Esempio n. 23
0
void UntangleWrapper::run_wrapper( MeshDomainAssoc* mesh_and_domain,
                                   ParallelMesh* pmesh,
                                   Settings* settings,
                                   QualityAssessor* qa,
                                   MsqError& err )
{
  Instruction::initialize_vertex_byte( mesh_and_domain, settings, err ); MSQ_ERRRTN(err);

  Mesh* mesh = mesh_and_domain->get_mesh();

    // get some global mesh properties
  SimpleStats edge_len, lambda;
  std::auto_ptr<MeshUtil> tool(new MeshUtil( mesh, settings ));
  tool->edge_length_distribution( edge_len, err ); MSQ_ERRRTN(err);
  tool->lambda_distribution( lambda, err ); MSQ_ERRRTN(err);
  tool.reset(0);
  
    // get target metrics from user perferences
  TSizeNB1 mu_size;
  TShapeSize2DNB1 mu_shape_2d;
  TShapeSize3DNB1 mu_shape_3d;
  TMixed mu_shape( &mu_shape_2d, &mu_shape_3d );
  std::auto_ptr<TMetric> mu;
  if (qualityMetric == BETA) {
    double beta = metricConstant;
    if (beta < 0) 
      beta = (lambda.average()*lambda.average())/20;
    //std::cout << "beta= " << beta << std::endl;
    mu.reset(new TUntangleBeta( beta ));
  }
  else {
    TMetric* sub = 0;
    if (qualityMetric == SIZE)
      sub = &mu_size;
    else 
      sub = &mu_shape;
    if (metricConstant >= 0) 
      mu.reset(new TUntangleMu( sub, metricConstant ));
    else 
      mu.reset(new TUntangleMu( sub ));
  }
    
    // define objective function
  IdealShapeTarget base_target;
  LambdaConstant target( lambda.average(), &base_target );
  TQualityMetric metric_0(&target, mu.get());
  ElementPMeanP metric( 1.0, &metric_0 );
  PMeanPTemplate objfunc( 1.0, &metric );
  
    // define termination criterion
  double eps = movementFactor * (edge_len.average() - edge_len.standard_deviation());
  TerminationCriterion inner("<type:untangle_inner>", TerminationCriterion::TYPE_INNER), 
    outer("<type:untangle_outer>", TerminationCriterion::TYPE_OUTER);
  outer.add_untangled_mesh();
  if (doCulling) 
    inner.cull_on_absolute_vertex_movement( eps );
  else
    outer.add_absolute_vertex_movement( eps );
  if (maxTime > 0.0) 
    outer.add_cpu_time( maxTime );
  inner.add_iteration_limit( NUM_INNER_ITERATIONS );
  if (maxIterations > 0)
    outer.add_iteration_limit(maxIterations);
  
    // construct solver
  SteepestDescent solver( &objfunc );
  solver.use_element_on_vertex_patch();
  solver.set_inner_termination_criterion( &inner );
  solver.set_outer_termination_criterion( &outer );
  if (doJacobi)
    solver.do_jacobi_optimization();
  else
    solver.do_gauss_optimization();
  
    // Run 
  qa->add_quality_assessment( &metric );
  InstructionQueue q;
  q.add_quality_assessor( qa, err ); MSQ_ERRRTN(err);
  q.set_master_quality_improver( &solver, err ); MSQ_ERRRTN(err);
  q.add_quality_assessor( qa, err ); MSQ_ERRRTN(err);
  q.run_common( mesh_and_domain, pmesh, settings, err ); MSQ_ERRRTN(err);
}
Esempio n. 24
0
void run_test( Grouping grouping, int of_power, Weight w, const string filename )
{
    MsqError err;

    IdentityTarget target;
    TSquared target_metric;
    AffineMapMetric qual_metric( &target, &target_metric );
    ElementPMeanP elem_metric( of_power, &qual_metric );
    QualityMetric* qm_ptr = (grouping == ELEMENT) ? (QualityMetric*)&elem_metric : (QualityMetric*)&qual_metric;

    PMeanPTemplate OF( of_power, qm_ptr );
    ConjugateGradient solver( &OF );
    TerminationCriterion tc;
    TerminationCriterion itc;
    tc.add_absolute_vertex_movement( 1e-4 );
    itc.add_iteration_limit( 2 );
#ifdef USE_GLOBAL_PATCH
    solver.use_global_patch();
    solver.set_inner_termination_criterion( &tc );
#else
    solver.use_element_on_vertex_patch();
    solver.set_inner_termination_criterion( &itc );
    solver.set_outer_termination_criterion( &tc );
#endif

    MeshImpl mesh, expected_mesh;
    mesh.read_vtk( SRCDIR "/initial.vtk", err );
    CHKERR(err)
//  expected_mesh.read_vtk( (filename + ".vtk").c_str(), err ); CHKERR(err)

    PlanarDomain plane( PlanarDomain::XY );

    MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &plane);

    MetricWeight mw( &qual_metric );
    InverseMetricWeight imw( &qual_metric );
    WeightReader reader;
    if (w == METRIC) {
        TargetWriter writer( 0, &mw );
        InstructionQueue tq;
        tq.add_target_calculator( &writer, err );
        tq.run_instructions( &mesh_and_domain, err );
        CHKERR(err);
        qual_metric.set_weight_calculator( &reader );
    }
    else if (w == INV_METRIC) {
        TargetWriter writer( 0, &imw );
        InstructionQueue tq;
        tq.add_target_calculator( &writer, err );
        tq.run_instructions( &mesh_and_domain, err );
        CHKERR(err);
        qual_metric.set_weight_calculator( &reader );
    }

    InstructionQueue q;
    q.set_master_quality_improver( &solver, err );
    q.run_instructions( &mesh_and_domain, err );
    CHKERR(err)
    /*
      vector<Mesh::VertexHandle> vemain.cpprts;
      vector<MsqVertex> mesh_coords, expected_coords;
      mesh.get_all_vertices( verts, err ); CHKERR(err)
      mesh_coords.resize(verts.size());
      mesh.vertices_get_coordinates( arrptr(verts), arrptr(mesh_coords), verts.size(), err ); CHKERR(err)
      expected_mesh.get_all_vertices( verts, err ); CHKERR(err)
      expected_coords.resize(verts.size());
      expected_mesh.vertices_get_coordinates( arrptr(verts), arrptr(expected_coords), verts.size(), err ); CHKERR(err)
      if (expected_coords.size() != mesh_coords.size()) {
        cerr << "Invlid expected mesh.  Vertex count doesn't match" << endl;
        exit(1);
      }

      unsigned error_count = 0;
      for (size_t i = 0; i < mesh_coords.size(); ++i)
        if ((expected_coords[i] - mesh_coords[i]).length_squared() > epsilon*epsilon)
          ++error_count;

      if (!error_count)
        cout << filename << " : SUCCESS" << endl;
      else
        cout << filename << " : FAILURE (" << error_count
             << " vertices differ by more than " << epsilon << ")" << endl;
    */
    if (write_results)
        mesh.write_vtk( (filename + ".results.vtk").c_str(), err );
    CHKERR(err)
}
Esempio n. 25
0
bool
Loop::hoistInstructions(InstructionQueue &toHoist, InstructionQueue &boundsChecks)
{
    // Hoist bounds checks first, so that hoistBoundsCheck can test for
    // invariant instructions, but delay actual insertion until the end to
    // handle dependencies on loop invariant instructions.
    InstructionQueue hoistedChecks;
    for (size_t i = 0; i < boundsChecks.length(); i++) {
        MBoundsCheck *ins = boundsChecks[i]->toBoundsCheck();
        if (isLoopInvariant(ins) || !isInLoop(ins))
            continue;

        // Try to find a test dominating the bounds check which can be
        // transformed into a hoistable check. Stop after the first such check
        // which could be transformed (the one which will be the closest to the
        // access in the source).
        MBasicBlock *block = ins->block();
        while (true) {
            BranchDirection direction;
            MTest *branch = block->immediateDominatorBranch(&direction);
            if (branch) {
                MInstruction *upper, *lower;
                tryHoistBoundsCheck(ins, branch, direction, &upper, &lower);
                if (upper && !hoistedChecks.append(upper))
                    return false;
                if (lower && !hoistedChecks.append(lower))
                    return false;
                if (upper || lower) {
                    ins->block()->discard(ins);
                    break;
                }
            }
            MBasicBlock *dom = block->immediateDominator();
            if (dom == block)
                break;
            block = dom;
        }
    }

    // Move all instructions to the preLoop_ block just before the control instruction.
    for (size_t i = 0; i < toHoist.length(); i++) {
        MInstruction *ins = toHoist[i];

        // Loads may have an implicit dependency on either stores (effectful instructions) or
        // control instructions so we should never move these.
        JS_ASSERT(!ins->isControlInstruction());
        JS_ASSERT(!ins->isEffectful());
        JS_ASSERT(ins->isMovable());

        if (checkHotness(ins->block())) {
            ins->block()->moveBefore(preLoop_->lastIns(), ins);
            ins->setNotLoopInvariant();
        }
    }

    for (size_t i = 0; i < hoistedChecks.length(); i++) {
        MInstruction *ins = hoistedChecks[i];
        preLoop_->insertBefore(preLoop_->lastIns(), ins);
    }

    return true;
}
Esempio n. 26
0
int main( int argc, char* argv[] )
{
  const double default_fraction = 0.05;
  const double zero = 0.0;
  int one = 1;
  CLArgs::ToggleArg allow_invalid( false );
  CLArgs::DoubleRangeArg rand_percent( default_fraction, &zero, 0 );
  CLArgs::IntRangeArg unoptimize( 0, &one, 0 );
  
  CLArgs args( "vtkrandom",
               "Randomize mesh vertex locations.",
               "Read VTK file, randomize locations of containded vertices, and re-write file." );
  args.toggle_flag( INVALID_FLAG, "Allow inverted elements in output", &allow_invalid );
  args.double_flag( PERCENT_FLAG, "fract", "Randomize fraction", &rand_percent );
  args.int_flag( UNOPTIMIZE_FLAG, "N", "Use UnOptimizer with N passes rather than Randomize", &unoptimize );
  add_domain_args( args );
  args.add_required_arg( "input_file" );
  args.add_required_arg( "output_file" );

  std::vector<std::string> files;
  if (!args.parse_options( argc, argv, files, std::cerr )) {
    args.print_usage( std::cerr );
    exit(1);
  }
  std::string input_file = files[0];
  std::string output_file = files[1];
  
  MsqError err;
  MeshImpl mesh;
  mesh.read_vtk( input_file.c_str(), err );
  if (err) {
    std::cerr << "ERROR READING FILE: " << input_file << std::endl
                    << err << std::endl;
    return 2;
  }
  MeshDomain* domain = process_domain_args( &mesh );

  TerminationCriterion tc;
  QualityAssessor qa( false );
  InstructionQueue q;
  Randomize op( rand_percent.value() );
  IdealWeightInverseMeanRatio metric;
  PMeanPTemplate of( 1, &metric );
  UnOptimizer op2( &of );
  if (unoptimize.seen()) {
    tc.add_iteration_limit( unoptimize.value() );
    op2.set_outer_termination_criterion( &tc );
    q.add_preconditioner( &op, err );
    q.set_master_quality_improver( &op2, err );
  }
  else {
    q.set_master_quality_improver( &op, err );
  }
  q.add_quality_assessor( &qa, err );
  q.run_instructions( &mesh, domain, err );
  if (err) {
    std::cerr << err << std::endl;
    return 3;
  }

  int inverted, junk;
  if (qa.get_inverted_element_count( inverted, junk, err ) && inverted ) {
    if (allow_invalid.value())
      std::cerr << "Warning: output mesh contains " << inverted << " inverted elements" << std::endl;
    else {
      std::cerr << "Error: output mesh contains " << inverted << " inverted elements" << std::endl;
      return 4;
    }
  }
  
  mesh.write_vtk( output_file.c_str(), err );
  if (err) {
    std::cerr << "ERROR WRITING FILE: " << output_file << std::endl
                    << err << std::endl;
    return 2;
  }
  
  return 0;
}
    void PMMShapeSizeOrientImprover::run_wrapper( Mesh* mesh,
                                                  ParallelMesh* pmesh,
                                                  MeshDomain* domain,
                                                  Settings* settings,
                                                  QualityAssessor* qa,
                                                  MsqError& err )
    {
      InstructionQueue q;
  
      // Set up barrier metric to see if mesh contains inverted elements
      TShapeB1 mu_b;
      IdealShapeTarget w_ideal;
      TQualityMetric barrier( &w_ideal, &mu_b );
  
      // Check for inverted elements in the mesh
      QualityAssessor inv_check( &barrier );
      //inv_check.disable_printing_results();
      q.add_quality_assessor( &inv_check, err );  MSQ_ERRRTN(err);
      q.run_common( mesh, pmesh, domain, settings, err ); MSQ_ERRRTN(err);
      q.remove_quality_assessor( 0, err ); MSQ_ERRRTN(err);
      const QualityAssessor::Assessor* inv_b = inv_check.get_results( &barrier );
      //const bool use_barrier = (0 == inv_b->get_invalid_element_count());
      std::cout << "tmp srk PMMShapeSizeOrientImprover::run_wrapper get_invalid_element_count= " 
                << inv_b->get_invalid_element_count() << std::endl;
  
      // Create remaining metric instances
      TShapeNB1 mu;
      TShapeSizeOrientNB1 mu_o;
      TShapeSizeOrientB1 mu_ob;
  
      // Select which target metrics to use
      //TMetric *mu_p, *mu_op;
      //if (use_barrier) {
      //  mu_p = &mu_b;
      //  mu_op = &mu_ob;
      //}
      //else {
      //  mu_p = &mu;
      //  mu_op = &mu_o;
      //}
  
      // Set up target and weight calculators
      std::string altCoordName = "msq_jacobi_temp_coords"; // FIXME
      bool should_clean_up_tag_data = true; // default
      TagVertexMesh init_mesh( err, pmesh ? (Mesh*)pmesh : mesh, should_clean_up_tag_data, altCoordName );  MSQ_ERRRTN(err);
      ReferenceMesh ref_mesh( &init_mesh );
      RefMeshTargetCalculator w_init( &ref_mesh );

      //TetDihedralWeight c_dihedral( &ref_mesh, dCutoff, aVal );
      //RemainingWeight c_remaining( &c_dihedral );
  
      // Create objective function
      //       TQualityMetric metric1( &w_ideal, &c_dihedral,  mu_p  );
      //       TQualityMetric metric2( &w_init,  &c_remaining, mu_op );
      //       AddQualityMetric of_metric( &metric1, &metric2, err );  MSQ_ERRRTN(err);
      TQualityMetric of_metric( &w_init, &mu_o );
      PMeanPTemplate obj_func( 1.0, &of_metric );
  
      // Create optimizer
      //TrustRegion solver( &obj_func );
      FeasibleNewton solver( &obj_func );
      TerminationCriterion term, ptc;
      term.add_iteration_limit( iterationLimit );
      term.add_absolute_vertex_movement( maxVtxMovement );
      ptc.add_iteration_limit( pmesh ? parallelIterations : 1 );
      solver.set_inner_termination_criterion( &term );
      solver.set_outer_termination_criterion( &ptc );
  
      // Create instruction queue
      //qa->add_quality_assessment( &metric1 );
      //qa->add_quality_assessment( &metric2 );
      qa->add_quality_assessment( &of_metric );
      q.add_quality_assessor( qa, err ); MSQ_ERRRTN(err);
      q.set_master_quality_improver( &solver, err ); MSQ_ERRRTN(err);
      q.add_quality_assessor( qa, err ); MSQ_ERRRTN(err);

      // Optimize mesh
      q.run_common( mesh, pmesh, domain, settings, err ); MSQ_CHKERR(err);  
    }
Esempio n. 28
0
bool smooth_mesh( Mesh* mesh, Mesh* ref_mesh,
                  Mesh::VertexHandle free_vertex_at_origin, 
                  Vector3D initial_free_vertex_position,
                  QualityMetric* metric )
{
  Mesquite::MsqPrintError err(cout);
  const Vector3D origin( 0, 0, 0 );
  
  // print a little output so we know when we died
  std::cout << 
  "**************************************************************************" 
  << std::endl << 
  "* Smoothing..."
  << std::endl << 
  "* Metric: " << metric->get_name()
  << std::endl << 
  "* Apex position: " << initial_free_vertex_position
  << std::endl //<< 
  //"**************************************************************************" 
  << std::endl;

  
  // Set free vertex to specified position
  mesh->vertex_set_coordinates( free_vertex_at_origin, 
                                initial_free_vertex_position,
                                err );
  CPPUNIT_ASSERT(!err);

  // Create an InstructionQueue
  InstructionQueue Q;

  // Set up objective function
  LPtoPTemplate obj_func(metric, 1, err);
  CPPUNIT_ASSERT(!err);

  // Create solver
  FeasibleNewton solver( &obj_func, true );
  CPPUNIT_ASSERT(!err);
  solver.use_global_patch();
  CPPUNIT_ASSERT(!err);

  // Set stoping criteria for solver
  TerminationCriterion tc_inner;
  tc_inner.add_absolute_vertex_movement( 1e-6 );
  solver.set_inner_termination_criterion(&tc_inner);
   
  TerminationCriterion tc_outer;
  tc_outer.add_iteration_limit( 1 );
  solver.set_outer_termination_criterion(&tc_outer);
   
  // Add solver to queue
  Q.set_master_quality_improver(&solver, err); 
  CPPUNIT_ASSERT(!err);
 
  // And smooth...
  Q.run_instructions(mesh, err); 
  CPPUNIT_ASSERT(!err);
  
  // Verify that vertex was moved back to origin
  MsqVertex vtx;
  mesh->vertices_get_coordinates( &free_vertex_at_origin, &vtx, 1, err );
  CPPUNIT_ASSERT( !err );
  Vector3D position = vtx;
  
  // print a little output so we know when we died
  std::cout //<< 
  //"**************************************************************************" 
  << std::endl << 
  "* Done Smoothing:"
  << std::endl << 
  "* Metric: " << metric->get_name()
  << std::endl << 
  "* Apex position: " << position
  << std::endl <<  
  "**************************************************************************" 
  << std::endl;
  
  CPPUNIT_ASSERT( position.within_tolerance_box( Vector3D(0,0,0), TOL ) );
  return false;
}
Esempio n. 29
0
int main( int argc, char* argv[] )
{
  MeshParams input_params, reference_params;
  bool fixed_boundary_vertices, feas_newt_solver;
  TerminationCriterion::TimeStepFileType write_timestep_files;
  std::string output_file_name;
  int num_iterations;
  
  parse_options( argv, argc,
                 input_params, reference_params,
                 output_file_name,
                 fixed_boundary_vertices,
                 write_timestep_files,
                 feas_newt_solver,
                 num_iterations );
  
  MsqError err;
  MeshImpl mesh, refmesh;
  XYRectangle domain( input_params.w, input_params.h );
  create_input_mesh( input_params, fixed_boundary_vertices, mesh, err ); CHECKERR
  create_input_mesh( reference_params, fixed_boundary_vertices, refmesh, err ); CHECKERR
  domain.setup( &mesh, err ); CHECKERR

  ReferenceMesh rmesh( &refmesh );
  RefMeshTargetCalculator tc( &rmesh );
  TShapeB1 tm;
  TQualityMetric qm( &tc, &tm );
  
  PMeanPTemplate of( 1.0, &qm );
  ConjugateGradient cg( &of );
  cg.use_element_on_vertex_patch();
  FeasibleNewton fn( &of );
  fn.use_element_on_vertex_patch();
  VertexMover* solver = feas_newt_solver ? (VertexMover*)&fn : (VertexMover*)&cg;
  
  TerminationCriterion inner, outer;
  inner.add_iteration_limit( INNER_ITERATES );
  outer.add_iteration_limit( num_iterations );
  if (write_timestep_files != TerminationCriterion::NOTYPE) 
    outer.write_mesh_steps( base_name( output_file_name ).c_str(), write_timestep_files );
  solver->set_inner_termination_criterion( &inner );
  solver->set_outer_termination_criterion( &outer );
  
  QualityAssessor qa( &qm );
  InstructionQueue q;
  q.add_quality_assessor( &qa, err );
  q.set_master_quality_improver( solver, err );
  q.add_quality_assessor( &qa, err );
  
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &domain);
  q.run_instructions( &mesh_and_domain, err ); CHECKERR
  
  mesh.write_vtk( output_file_name.c_str(), err ); CHECKERR
  
    // check for inverted elements
  int inv, unk;
  qa.get_inverted_element_count( inv, unk, err );
  if (inv) {
    std::cerr << inv << " inverted elements in final mesh" << std::endl;
    return INVERTED_ELEMENT;
  }
  else if (unk) {
    std::cerr << unk << " degenerate elements in final mesh" << std::endl;
    return DEGENERATE_ELEMENT;
  }
    
    // find the free vertex
  std::vector<Mesh::VertexHandle> vertices;
  mesh.get_all_vertices( vertices, err );
  if (vertices.empty()) {
    std::cerr << "Mesh contains no vertices" << std::endl;
    return USAGE_ERROR;
  }
  std::vector<unsigned short> dof( vertices.size(), 0 );
  domain.domain_DoF( arrptr(vertices), arrptr(dof), vertices.size(), err ); CHECKERR
  int idx = std::find(dof.begin(), dof.end(), 2) - dof.begin();
  const Mesh::VertexHandle free_vertex = vertices[idx];
  MsqVertex coords;
  mesh.vertices_get_coordinates( &free_vertex, &coords,1, err ); CHECKERR
  
    // calculate optimal position for vertex
  const double xf = reference_params.x / reference_params.w;
  const double yf = reference_params.y / reference_params.h;
  Vector3D expect( xf * input_params.w, yf * input_params.h, 0 );

  // Test that we aren't further from the expected location
  // than when we started. 
  const Vector3D init( input_params.x, input_params.y, 0 );
  if ((coords - expect).length() > (init - expect).length()) {
    std::cerr << "Vertex moved away from expected optimal position: "
                    << "(" << coords[0] << ", " << coords[1] << std::endl;
    return WRONG_DIRECTION;
  }
  
    // check if vertex moved MIN_FRACT of the way from the original position
    // to the desired one in the allowed iterations
  const double MIN_FRACT = 0.2; // 20% of the way in 10 iterations
  const double fract = (coords - init).length() / (expect - init).length();
  if (fract < MIN_FRACT) {
    std::cerr << "Vertex far from optimimal location" << std::endl
                    << "  Expected: (" << expect[0] << ", " << expect[1] << ", " << expect[2] << ")" << std::endl
                    << "  Actual:   (" << coords[0] << ", " << coords[1] << ", " << coords[2] << ")" << std::endl;
    return FAR_FROM_TARGET;
  }
  
    // check if vertex is at destired location
  const double EPS = 5e-2; // allow a little leway
  if (fabs(coords[0] - expect[0]) > EPS * input_params.w ||
      fabs(coords[1] - expect[1]) > EPS * input_params.h ||
      fabs(expect[2]            ) > EPS                  ) {
    std::cerr << "Vertex not at optimimal location" << std::endl
                    << "  Expected: (" << expect[0] << ", " << expect[1] << ", " << expect[2] << ")" << std::endl
                    << "  Actual:   (" << coords[0] << ", " << coords[1] << ", " << coords[2] << ")" << std::endl;
    return NOT_AT_TARGET;
  }
  
  return 0;
}
Esempio n. 30
0
void InstructionQueueTest::test_add_remove_vertex_slaver()
{
  InstructionQueue q;
  DummyVertexSlaver s1, s2;
  MsqPrintError err( std::cerr );
  
  CPPUNIT_ASSERT( q.get_slaved_ho_node_mode() != Settings::SLAVE_CALCULATED );
  q.add_vertex_slaver( &s1, err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_EQUAL( Settings::SLAVE_CALCULATED, q.get_slaved_ho_node_mode() );
  q.add_vertex_slaver( &s2, err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_EQUAL( Settings::SLAVE_CALCULATED, q.get_slaved_ho_node_mode() );
  q.remove_vertex_slaver( &s2, err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_EQUAL( Settings::SLAVE_CALCULATED, q.get_slaved_ho_node_mode() );
  q.remove_vertex_slaver( &s2, err );
  CPPUNIT_ASSERT(err);
  err.clear();
  CPPUNIT_ASSERT_EQUAL( Settings::SLAVE_CALCULATED, q.get_slaved_ho_node_mode() );
  q.remove_vertex_slaver( &s1, err );
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT_EQUAL( Settings::SLAVE_ALL, q.get_slaved_ho_node_mode() );
}