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