MeshKit  1.0
test_intassign.cpp
Go to the documentation of this file.
00001 
00007 // ia_main.cpp 
00008 // test IntervalMatching interface IAInterface for MeshKit
00009 
00010 #include "TestUtil.hpp"
00011 #include "meshkit/MKCore.hpp"
00012 
00013 #include "meshkit/IAInterface.hpp"
00014 #include "meshkit/IAVariable.hpp"
00015 #include "meshkit/TFIMapping.hpp"
00016 
00017 #include <stdio.h>
00018 #include <iostream>
00019 #ifdef HAVE_ACIS
00020     #define INTASSIGN_TEST_FILE "quadface.sat"
00021 #elif defined(HAVE_OCC)
00022     #define INTASSIGN_TEST_FILE "quadface.stp"
00023 #else
00024     #define INTASSIGN_TEST_FILE "squaresurf.facet"
00025 #endif
00026 
00027 MeshKit::MKCore *mk;
00028 
00029 MeshKit::IAInterface *new_ia_interface()
00030 {
00031   return
00032       (MeshKit::IAInterface*) mk->construct_meshop("IntervalAssignment");
00033 }
00034 
00035 void delete_ia_interface(MeshKit::IAInterface *)
00036 {
00037   //nada, mk takes care of it
00038   ;
00039 }
00040 
00041 bool check_solution_correctness( MeshKit::IAInterface *ia_interface, 
00042                                  std::vector< std::pair<int,int> > &correct_solution)
00043 {
00044   const bool verbose_output = true;
00045   const bool debug = false;
00046   bool all_correct = true;
00047   MeshKit::IAInterface::VariableVec::const_iterator b = ia_interface->variables_begin();
00048   MeshKit::IAInterface::VariableVec::const_iterator e = ia_interface->variables_end();
00049   MeshKit::IAInterface::VariableVec::const_iterator i = b;
00050   unsigned int c = 0;
00051   if (debug)
00052     std::cout << "Checking Solution Correctness" << std::endl;
00053   for ( ; i != e; ++i, ++c )
00054     {
00055       const MeshKit::IAVariable *v = *i;
00056       assert(v);
00057       const int x = v->get_solution();
00058       assert(c < correct_solution.size() );
00059       const int lo = correct_solution[c].first;
00060       const int hi = correct_solution[c].second;
00061       if (debug)
00062         std::cout << "Checking variable " << c << " solution " << x << " in "
00063                   << "[" << lo << "," << hi << "]?" << std::endl;
00064       if (x < lo)
00065         {
00066           if (verbose_output)
00067             std::cout << "ERROR: Variable " << c << " solution " << x << " BELOW "
00068                       << "[" << lo << "," << hi << "]" << std::endl;
00069           all_correct = false;
00070         }
00071       if (x > hi)
00072         {
00073           if (verbose_output)
00074             std::cout << "ERROR: Variable " << c << " solution " << x << " ABOVE "
00075                       << "[" << lo << "," << hi << "]" << std::endl;
00076           all_correct = false;
00077         }
00078     }
00079   if (debug)
00080     std::cout << "done checking solution correctness." << std::endl;
00081   return all_correct;
00082 }
00083 
00084 void set_decoupled_pairs(MeshKit::IAInterface *ia_interface, 
00085                          int num_pairs, double goal1, double goal2,
00086                          std::vector< std::pair<int,int> > &correct_solution)
00087 {
00088   // trivial 2-sided mapping problem
00089   // we can make multiple pairs, each pair is independent,
00090   // and pair i (in 0..num_pairs-1) has sides with one curve each with goals
00091   // i+goal1 and i+goal2,
00092   //
00093   // test scalability, relaxed nlp: 100,000 constraints in 1 second. milp: 40 variables in 1 second, grows exponentially!
00094   for (int i = 0; i<num_pairs; ++i)
00095     {
00096       // goals x_{2i} = 2, x_{2i+1} = 2
00097       // x_{2i}, goal: i + goal1
00098       const double g1 = i + goal1;
00099       const double g2 = i + goal2;
00100       MeshKit::IAVariable *v1 = ia_interface->create_variable( NULL, MeshKit::SOFT, g1);
00101       MeshKit::IAVariable *v2 = ia_interface->create_variable( NULL, MeshKit::SOFT, g2);
00102       const double compromise = sqrt( g1 * g2 );
00103       double lo = floor(compromise);
00104       if ( ( compromise - lo ) < 0.1 )
00105         --lo;
00106       if ( lo < 1. )
00107         lo = 1.;
00108       double hi = ceil(compromise);
00109       if ( (hi - compromise) < 0.1 )
00110         ++hi;
00111       correct_solution.push_back( std::make_pair( lo, hi ) );
00112       correct_solution.push_back( std::make_pair( lo, hi ) );
00113 
00114       // constrain x_{2i} - x_{2i+1} = 0
00115       MeshKit::IAInterface::IAVariableVec side1, side2;
00116       side1.push_back(v1);
00117       side2.push_back(v2);
00118       ia_interface->constrain_sum_equal(side1, side2);
00119     }
00120 }
00121 
00122 
00123 void set_mapping_chain( MeshKit::IAInterface *ia_interface, const int num_sides, 
00124                         const bool grow_goal_by_i,
00125                         const int goal_m1, const int goal_m2,
00126                         const int num_curve_min, const int num_curve_max )
00127 {
00128   // test problem 3, sides with more than one variable, with random goals
00129   printf("constructing coupled test problem - mapping chain\n");
00130   srand(10234);
00131   MeshKit::IAInterface::IAVariableVec side1, side2;
00132   int num_vars = 0;
00133   for (int i = 0; i<num_sides; ++i)
00134     {
00135       // move side2 to side1
00136       side2.swap( side1 );
00137 
00138       // create new side2
00139       side2.clear();
00140       assert( num_curve_min > 0 );
00141       int num_curves = num_curve_min;
00142       if ( num_curve_max > num_curve_min )
00143         num_curves += (rand() % (1 + num_curve_max - num_curve_min) );
00144       for (int j = 0; j < num_curves; j++)
00145         {
00146           int goal_intervals = (1 + (rand() % goal_m1)) * (1 + (rand() % goal_m2));
00147           if (grow_goal_by_i)
00148             goal_intervals += num_vars;
00149           MeshKit::IAVariable *v = ia_interface->create_variable( NULL, MeshKit::SOFT, goal_intervals);
00150           side2.push_back(v);
00151         }
00152 
00153       // if we have two non-trivial opposite sides, then constrain them to be equal
00154       if (side1.size() && side2.size())
00155         {
00156           ia_interface->constrain_sum_equal(side1, side2);
00157         }
00158 
00159       // add a sum-even constraint
00160       if (i==0)
00161         {
00162           // printf("sum-even side: %d", i);
00163           assert( side2.size() );
00164           ia_interface->constrain_sum_even(side2);
00165         }
00166 
00167       // todo: try some hard-sets and non-trivial rhs
00168     }
00169 }
00170 
00171 // sum-even constraints test problems
00172 /*
00173   // test problem 4, a simple sum-even constraint
00174   int num_surfaces = 12; // 12
00175   int num_curves_per_surface = 4; // 4
00176   int num_shared_curves = 1; // 2
00177   
00178   int num_curves = 0;
00179   for (int i = 0; i < num_surfaces; ++i)
00180   {
00181     // gather the indices for the sum-even constraint
00182     int start_curve = num_curves - num_shared_curves;
00183     if (start_curve < 0)
00184       start_curve = 0;
00185     std::vector<int>curve_indices;
00186     if (debugging)
00187       printf("%d sum-even:",i);
00188     for (int j = 0; j < num_curves_per_surface; ++j)
00189     {
00190       curve_indices.push_back(start_curve+j);
00191       if (debugging)
00192         printf(" %d",start_curve+j);
00193     }
00194     num_curves = start_curve + num_curves_per_surface;
00195     const int rhs = 0; // test 0, -1
00196     constrain_sum_even(curve_indices,rhs);
00197     if (debugging)
00198       printf(" =%d\n",rhs);
00199   }
00200   // assign random goals to the curves
00201   for (int i = (int) I.size(); i < num_curves; ++i )
00202   {
00203     double goal = 1 + ((double) (rand() % 59)) / 10.; // 1 to 6.9
00204     // force an odd sum for testing purposes
00205     //if (i==0)
00206     //  goal += 1.;
00207     I.push_back(goal);
00208   }
00209 */
00210 
00211 void test_one_pair()
00212 {
00213   MeshKit::IAInterface *ia_interface = new_ia_interface();
00214   ia_interface->destroy_data();
00215 
00216   std::vector< std::pair<int,int> > correct_solution;
00217   set_decoupled_pairs(ia_interface, 1, 1, 3, correct_solution);
00218   //  set_decoupled_pairs(ia_interface, 1, 3.2, 12.1, correct_solution);
00219   ia_interface->execute_this();
00220   bool solution_correct = check_solution_correctness( ia_interface, correct_solution );
00221   CHECK( solution_correct );
00222 }
00223 
00224 void test_many_pairs()
00225 {
00226   MeshKit::IAInterface *ia_interface = new_ia_interface();
00227   ia_interface->destroy_data();
00228 
00229   std::vector< std::pair<int,int> > correct_solution;
00230   set_decoupled_pairs(ia_interface, 8, 3.2, 12.1, correct_solution);
00231   set_decoupled_pairs(ia_interface, 1, 3.2, 12.1, correct_solution);
00232   set_decoupled_pairs(ia_interface, 8, 7.7, 4.2, correct_solution);
00233   set_decoupled_pairs(ia_interface, 40, 1.1, 5.2, correct_solution);
00234   set_decoupled_pairs(ia_interface, 40, 1.6, 4.5, correct_solution);
00235   set_decoupled_pairs(ia_interface, 4, 1.5, 1.5, correct_solution);
00236   set_decoupled_pairs(ia_interface, 4, 1, 1, correct_solution);
00237   
00238   ia_interface->execute_this();
00239   
00240   bool solution_correct = check_solution_correctness( ia_interface, correct_solution );
00241   CHECK( solution_correct );
00242   
00243   delete_ia_interface( ia_interface );
00244 }
00245 
00246 void test_long_chain()
00247 {
00248   MeshKit::IAInterface *ia_interface = new_ia_interface();
00249   ia_interface->destroy_data();
00250   
00251   // test scalability: 20000 gives 20,000 constraints, 100,000 variables in 1 second relaxed solution
00252   set_mapping_chain(ia_interface, 16000, false, 3, 15, 2, 11);
00253   // goal distribution is gaussian in [1, 32]
00254 
00255   ia_interface->execute_this();
00256   
00257   // bool solution_defined = check_solution( ia_interface );
00258 
00259   delete_ia_interface( ia_interface );
00260 }
00261 
00262 
00263 void test_growing_chain()
00264 {
00265   // test problem 2
00266   // printf("constructing growing chain, coupled test problem\n");
00267   MeshKit::IAInterface *ia_interface = new_ia_interface();
00268   ia_interface->destroy_data();
00269   
00270   // goals are 1, 2, 3, 4, ... 16
00271   // one curve per side
00272   set_mapping_chain(ia_interface, 16, true, 1, 1, 1, 1);
00273 
00274   ia_interface->execute_this();
00275   
00276   // bool solution_defined = check_solution( ia_interface );
00277   
00278   delete_ia_interface( ia_interface );
00279 }
00280 
00281 void mapping_test() 
00282 {
00283   MeshKit::IAInterface *ia_interface = new_ia_interface();
00284   ia_interface->destroy_data();
00285 
00286   std::string file_name = TestDir + "/" + INTASSIGN_TEST_FILE;
00287   printf("opening %s\n", file_name.c_str());
00288   mk->load_geometry_mesh(file_name.c_str(), NULL);
00289 
00290   //check the number of geometrical edges
00291   MeshKit::MEntVector surfs, loops;
00292   mk->get_entities_by_dimension(2, surfs);
00293   MeshKit::ModelEnt *this_surf = (*surfs.rbegin());
00294 
00295   // request a specific size
00296   MeshKit::MEntVector curves;
00297   std::vector<int> senses, loop_sizes;
00298   this_surf->boundary(1, curves, &senses, &loop_sizes);
00299   CHECK_EQUAL(4, (int)curves.size());
00300 
00301   MeshKit::SizingFunction esize(mk, 5, 0.2);
00302   surfs[0]->sizing_function_index(esize.core_index());
00303   curves[0]->interval_firmness(MeshKit::SOFT);
00304   curves[1]->interval_firmness(MeshKit::SOFT);
00305   MeshKit::SizingFunction esizeTwo(mk, 8, 0.125);
00306   curves[2]->sizing_function_index(esizeTwo.core_index());
00307   curves[2]->interval_firmness(MeshKit::SOFT);
00308   MeshKit::SizingFunction esizeThree(mk, 4, 0.25);
00309   curves[3]->sizing_function_index(esizeThree.core_index());
00310   curves[3]->interval_firmness(MeshKit::SOFT);
00311 
00312 
00313   MeshKit::MEntVector side1, side2;
00314   side1.push_back(curves[0]); side2.push_back(curves[2]);
00315   ia_interface->constrain_sum_equal(ia_interface->make_constraint_group(side1),
00316                                     ia_interface->make_constraint_group(side2));
00317   side1.clear(); side2.clear();
00318   side1.push_back(curves[1]); side2.push_back(curves[3]);
00319   ia_interface->constrain_sum_equal(ia_interface->make_constraint_group(side1),
00320                                     ia_interface->make_constraint_group(side2));
00321 
00322   // if there are loops, and the loops have strictly less than 4 curves, then
00323   // ia_interface->constrain_sum_even( ia_interface->make_constraint_group(curves in loop) );
00324   
00325   //now, do the TFIMapping
00326   (MeshKit::TFIMapping*) mk->construct_meshop("TFIMapping", surfs);
00327   mk->setup_and_execute();
00328   mk->save_mesh("intassign.h5m");
00329   //
00330   delete_ia_interface( ia_interface );
00331 }
00332 
00333 int main(int argv, char *argc[])
00334 {
00335   // currently unable to create more than one mk called IntervalAssignment
00336   mk = new MeshKit::MKCore();
00337 
00338   int one_pair = RUN_TEST(test_one_pair);
00339   // run same test twice to check data clearing integrity
00340   int one_pair2 = RUN_TEST(test_one_pair);
00341   int many_pairs = RUN_TEST(test_many_pairs);
00342   int map_test =  RUN_TEST(mapping_test);
00343   int growing_chain = RUN_TEST(test_growing_chain);
00344   // int long_chain = RUN_TEST(test_long_chain);
00345 
00346   //  int expt = RUN_TEST(test_exception);
00347   //  int succ = RUN_TEST(test_success);
00348 
00349   delete mk;
00350   int success = one_pair + one_pair2 + many_pairs + map_test + growing_chain; // + !abrt + !expt + succ;
00351   return success;
00352 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines