MeshKit
1.0
|
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 }