1 /**
2  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3  * storing and accessing finite element mesh data.
4  *
5  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
6  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7  * retains certain rights in this software.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  */
15 
16 /**
17  * Zoltan: class to get a mesh from MOAB and write a Zoltan partition set for
18  * that mesh back into MOAB and to a file
19  *
20  */
21 
22 #ifndef ZOLTANPARTITIONER_HPP
23 #define ZOLTANPARTITIONER_HPP
24 
25 #include <stdlib.h>
26 #include "moab/PartitionerBase.hpp"
27 #include "zoltan_cpp.h"
28 #include <time.h>
29 
30 #ifdef MOAB_HAVE_CGM
31 #include <map>
32 #include "GeometryQueryTool.hpp"
33 #include "DLIList.hpp"
34 class RefEntity;
35 #endif
36 
37 extern "C"
38 {
39   int mbGetNumberOfAssignedObjects(void *userDefinedData, int *err);
40 
41   void mbGetObjectList(void *userDefinedData, int numGlobalIds, int numLids,
42                        ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids, int wgt_dim, float *obj_wgts,
43                        int *err);
44 
45   int mbGetObjectSize(void *userDefinedData, int *err);
46 
47   void mbGetObject(void *userDefinedData, int numGlobalIds, int numLids, int numObjs,
48                    ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids, int numDim, double *pts, int *err);
49 
50   void mbGetNumberOfEdges(void *userDefinedData, int numGlobalIds, int numLids,
51                           int numObjs,
52                           ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids,	int *numEdges,
53                           int *err);
54 
55   void mbGetEdgeList(void *userDefinedData, int numGlobalIds, int numLids,
56                      int numObjs,
57                      ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids, int *numEdges,
58                      ZOLTAN_ID_PTR nborGlobalIds, int *nborProcs, int wgt_dim,
59                      float *edge_wgts, int *err);
60 
61   void mbGetPart(void *userDefinedData, int numGlobalIds, int numLids,
62                  int numObjs, ZOLTAN_ID_PTR gids, ZOLTAN_ID_PTR lids,
63                  int *part, int *err);
64 
65   void mbShowError(int val, const char *s, int me);
66 
67   void mbPrintGlobalResult(const char *s,
68                            int begin, int import, int exp, int change);
69 }
70 
71 #include <vector>
72 
73 namespace moab {
74 
75   class ParallelComm;
76   class Interface;
77   class Range;
78 }
79 
80 using namespace moab;
81 
82   class ZoltanPartitioner : public PartitionerBase<int>
83   {
84 
85   public:
86     ZoltanPartitioner( Interface *impl = NULL,
87               const bool use_coords = false,
88               int argc = 0,
89               char **argv = NULL
90 #ifdef MOAB_HAVE_CGM
91               , GeometryQueryTool *gqt = NULL
92 #endif
93               );
94 
95 
96     virtual ~ZoltanPartitioner();
97 
98     ErrorCode balance_mesh(const char *zmethod,
99                            const char *other_method,
100                            const bool write_as_sets = true,
101                            const bool write_as_tags = false);
102 
103     virtual ErrorCode partition_mesh_and_geometry(const double part_geom_mesh_size,
104                                                   const int nparts,
105                                                   const char *zmethod,
106                                                   const char *other_method,
107                                                   double imbal_tol,
108                                                   const int part_dim = 3,
109                                                   const bool write_as_sets = true,
110                                                   const bool write_as_tags = false,
111                                                   const int obj_weight = 0,
112                                                   const int edge_weight = 0,
113                                                   const bool part_surf = false,
114                                                   const bool ghost = false,
115                                                   const bool spherical_coords = false,
116                                                   const bool print_time = false);
117 
118     virtual ErrorCode partition_mesh( const int nparts,
119                                       const char *method,
120                                       const int part_dim = 3,
121                                       const bool write_as_sets = true,
122                                       const bool write_as_tags = false,
123                                       const bool partition_tagged_sets = false,
124                                       const bool partition_tagged_ents = false,
125                                       const char *aggregating_tag = NULL,
126                                       const bool print_time = false);
127 
128       // given a processor assignment returned from Zoltan, write that as a
129       // processor assignment to MOAB
130     virtual ErrorCode write_partition(const int nparts, Range &elems,
131                               const int *assignment,
132                               const bool write_as_sets,
133                               const bool write_as_tags);
134 
135     // given x, y, z and a starting id, return where to send to each (x[i],y[i],z[i]) point
136     ErrorCode repartition(std::vector<double> & x,std::vector<double>&y, std::vector<double> &z, int StartID,
137         const char * zmethod, Range & localGIDs);
138 
139     // partition owned cell in a new number of parts, based on adjacency
140     // we might have some extra adjacencies expressed in extraAdjCellsId, which could point to a cell on a different task
141     ErrorCode  partition_owned_cells(Range & owned,  ParallelComm * pco, std::map<int, int> & extraAdjCellsId, std::map<int, int> procs,
142         int & numNewPartitions, std::map<int, Range> & distribution, int met);
143 
144 #ifdef MOAB_HAVE_CGM
145     ErrorCode write_partition(const int nparts,
146                               DLIList<RefEntity*> entities,
147                               const int *assignment,
148                               std::vector<double> &obj_weights,
149                               const bool part_surf,
150                               const bool ghost);
151 
152     ErrorCode partition_surface(const int nparts,
153                                 DLIList<RefEntity*> entities,
154                                 const int *assignment,
155                                 std::vector<double> &obj_weights);
156 #endif
157 
158       // put closure of entities in the part sets too
159     ErrorCode include_closure();
160 
161     // virtual ErrorCode write_file(const char *filename, const char *out_file);
162 
163     void SetOCTPART_Parameters(const char *oct_method);
164 
165     void SetPARMETIS_Parameters(const char *parmetis_method);
166 
167     void SetHypergraph_Parameters(const char *phg_method);
168 
169     void SetHSFC_Parameters();
170 
171     void SetRIB_Parameters();
172 
173     void SetRCB_Parameters();
174 
175   private:
176 
177     Zoltan *myZZ;
178 
179     Range partSets;
180 
181     int myNumPts;
182 
183     int argcArg;
184 
185     char **argvArg;
186 
187     int mbGlobalSuccess(int rc);
188 
189     void mbPrintGlobalResult(const char *s,
190                              int begin, int import, int exp, int change);
191 
192     void mbShowError(int val, const char *s);
193 
194       // given the dimension, assemble the vertices and store in coords and
195       // moab_ids
196     ErrorCode assemble_graph(const int dimension,
197                              std::vector<double> &coords,
198                              std::vector<int> &moab_ids,
199                              std::vector<int> &adjacencies,
200                              std::vector<int> &length,
201                              Range &elems, bool part_geom = false, const bool spherical_coords=false);
202 
203 #ifdef MOAB_HAVE_CGM
204     std::map<int, int> body_vertex_map, surf_vertex_map;
205 
206     ErrorCode assemble_graph(const int dimension,
207                              std::vector<double> &coords,
208                              std::vector<int> &moab_ids,
209                              std::vector<int> &adjacencies,
210                              std::vector<int> &length,
211                              std::vector<double> &obj_weights,
212                              std::vector<double> &edge_weights,
213                              std::vector<int> &parts,
214                              DLIList<RefEntity*> &entities,
215                              const double part_geom_mesh_size,
216                              const int n_part);
217 
218     ErrorCode partition_round_robin(const int n_part);
219 
220     ErrorCode partition_child_entities(const int dim,
221                                        const int n_part,
222                                        const bool partition_surf,
223                                        const bool ghost = false);
224 
225     double estimate_face_mesh_load(RefEntity* face, const double h);
226     double estimate_face_comm_load(RefEntity* face, const double h);
227 #endif
228 
229     void mbFinalizePoints(int npts, int numExport,
230                           ZOLTAN_ID_PTR exportLocalIDs, int *exportProcs,
231                           int **assignment);
232 
233     int mbInitializePoints(int npts, double *pts, int *ids,
234                            int *adjs, int *length,
235                            double *obj_weights = NULL,
236                            double *edge_weights = NULL,
237                            int *parts = NULL, bool part_geom = false);
238 
239 #ifdef MOAB_HAVE_CGM
240     GeometryQueryTool *gti;
241 #endif
242   };
243 
244 inline
partition_mesh(const int nparts,const char * method,const int part_dim,const bool write_as_sets,const bool write_as_tags,const bool,const bool,const char *,const bool print_time)245 ErrorCode ZoltanPartitioner::partition_mesh(const int nparts,
246                                             const char *method,
247                                             const int part_dim,
248                                             const bool write_as_sets,
249                                             const bool write_as_tags,
250                                             const bool ,
251                                             const bool ,
252                                             const char *,
253                                             const bool print_time)
254 {
255   return partition_mesh_and_geometry(-1.0, nparts, method, NULL,
256                                       1.03, part_dim,
257                                       write_as_sets, write_as_tags,
258                                       0, 0,
259                                       false, false,
260                                       false, print_time);
261 }
262 
263 #endif
264