~ubuntu-branches/ubuntu/trusty/scotch/trusty

« back to all changes in this revision

Viewing changes to src/libscotch/arch_torus.c

  • Committer: Bazaar Package Importer
  • Author(s): Christophe Prud'homme
  • Date: 2008-01-25 09:13:53 UTC
  • Revision ID: james.westby@ubuntu.com-20080125091353-zghdao60dfsyc2bt
Tags: upstream-5.0.1.dfsg
ImportĀ upstreamĀ versionĀ 5.0.1.dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2004,2007 ENSEIRB, INRIA & CNRS
 
2
**
 
3
** This file is part of the Scotch software package for static mapping,
 
4
** graph partitioning and sparse matrix ordering.
 
5
**
 
6
** This software is governed by the CeCILL-C license under French law
 
7
** and abiding by the rules of distribution of free software. You can
 
8
** use, modify and/or redistribute the software under the terms of the
 
9
** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
 
10
** URL: "http://www.cecill.info".
 
11
** 
 
12
** As a counterpart to the access to the source code and rights to copy,
 
13
** modify and redistribute granted by the license, users are provided
 
14
** only with a limited warranty and the software's author, the holder of
 
15
** the economic rights, and the successive licensors have only limited
 
16
** liability.
 
17
** 
 
18
** In this respect, the user's attention is drawn to the risks associated
 
19
** with loading, using, modifying and/or developing or reproducing the
 
20
** software by the user in light of its specific status of free software,
 
21
** that may mean that it is complicated to manipulate, and that also
 
22
** therefore means that it is reserved for developers and experienced
 
23
** professionals having in-depth computer knowledge. Users are therefore
 
24
** encouraged to load and test the software's suitability as regards
 
25
** their requirements in conditions enabling the security of their
 
26
** systems and/or data to be ensured and, more generally, to use and
 
27
** operate it in the same conditions as regards security.
 
28
** 
 
29
** The fact that you are presently reading this means that you have had
 
30
** knowledge of the CeCILL-C license and that you accept its terms.
 
31
*/
 
32
/************************************************************/
 
33
/**                                                        **/
 
34
/**   NAME       : arch_torus.c                            **/
 
35
/**                                                        **/
 
36
/**   AUTHOR     : Francois PELLEGRINI                     **/
 
37
/**                                                        **/
 
38
/**   FUNCTION   : This module handles the torus graph     **/
 
39
/**                target architectures.                   **/
 
40
/**                                                        **/
 
41
/**   DATES      : # Version 0.0  : from : 01 dec 1992     **/
 
42
/**                                 to   : 24 mar 1993     **/
 
43
/**                # Version 1.2  : from : 04 feb 1994     **/
 
44
/**                                 to   : 11 feb 1994     **/
 
45
/**                # Version 1.3  : from : 20 apr 1994     **/
 
46
/**                                 to   : 20 apr 1994     **/
 
47
/**                # Version 2.0  : from : 06 jun 1994     **/
 
48
/**                                 to   : 23 dec 1994     **/
 
49
/**                # Version 2.1  : from : 07 apr 1995     **/
 
50
/**                                 to   : 29 jun 1995     **/
 
51
/**                # Version 3.0  : from : 01 jul 1995     **/
 
52
/**                                 to     08 sep 1995     **/
 
53
/**                # Version 3.1  : from : 07 may 1996     **/
 
54
/**                                 to     22 jul 1996     **/
 
55
/**                # Version 3.2  : from : 16 oct 1996     **/
 
56
/**                                 to     14 may 1998     **/
 
57
/**                # Version 3.3  : from : 01 oct 1998     **/
 
58
/**                                 to     01 oct 1998     **/
 
59
/**                # Version 4.0  : from : 05 nov 2003     **/
 
60
/**                                 to     10 mar 2005     **/
 
61
/**                                                        **/
 
62
/************************************************************/
 
63
 
 
64
/*
 
65
**  The defines and includes.
 
66
*/
 
67
 
 
68
#define ARCH_TORUS
 
69
 
 
70
#include "module.h"
 
71
#include "common.h"
 
72
#include "arch.h"
 
73
#include "arch_torus.h"
 
74
 
 
75
/***********************************************/
 
76
/*                                             */
 
77
/* These are the 2-dimensional torus routines. */
 
78
/*                                             */
 
79
/***********************************************/
 
80
 
 
81
/* This routine loads the
 
82
** bidimensional torus architecture.
 
83
** It returns:
 
84
** - 0   : if the architecture has been successfully read.
 
85
** - !0  : on error.
 
86
*/
 
87
 
 
88
int
 
89
archTorus2ArchLoad (
 
90
ArchTorus2 * restrict const archptr,
 
91
FILE * restrict const       stream)
 
92
{
 
93
#ifdef SCOTCH_DEBUG_ARCH1
 
94
  if ((sizeof (ArchTorus2)    > sizeof (ArchDummy)) ||
 
95
      (sizeof (ArchTorus2Dom) > sizeof (ArchDomDummy))) {
 
96
    errorPrint ("archTorus2ArchLoad: invalid type specification");
 
97
    return     (1);
 
98
  }
 
99
#endif /* SCOTCH_DEBUG_ARCH1 */
 
100
 
 
101
  if ((intLoad (stream, &archptr->c[0]) +
 
102
       intLoad (stream, &archptr->c[1]) != 2) ||
 
103
      (archptr->c[0] < 1) || (archptr->c[1] < 1)) {
 
104
    errorPrint ("archTorus2ArchLoad: bad input");
 
105
    return     (1);
 
106
  }
 
107
 
 
108
  return (0);
 
109
}
 
110
 
 
111
/* This routine saves the
 
112
** bidimensional torus architecture.
 
113
** It returns:
 
114
** - 0   : if the architecture has been successfully written.
 
115
** - !0  : on error.
 
116
*/
 
117
 
 
118
int
 
119
archTorus2ArchSave (
 
120
const ArchTorus2 * const    archptr,
 
121
FILE * restrict const       stream)
 
122
{
 
123
#ifdef SCOTCH_DEBUG_ARCH1
 
124
  if ((sizeof (ArchTorus2)    > sizeof (ArchDummy)) ||
 
125
      (sizeof (ArchTorus2Dom) > sizeof (ArchDomDummy))) {
 
126
    errorPrint ("archTorus2ArchSave: invalid type specification");
 
127
    return     (1);
 
128
  }
 
129
#endif /* SCOTCH_DEBUG_ARCH1 */
 
130
 
 
131
  if (fprintf (stream, "%ld %ld ",
 
132
               (long) archptr->c[0],
 
133
               (long) archptr->c[1]) == EOF) {
 
134
    errorPrint ("archTorus2ArchSave: bad output");
 
135
    return     (1);
 
136
  }
 
137
 
 
138
  return (0);
 
139
}
 
140
 
 
141
/* This function returns the smallest number
 
142
** of terminal domain included in the given
 
143
** domain.
 
144
*/
 
145
 
 
146
ArchDomNum
 
147
archTorus2DomNum (
 
148
const ArchTorus2 * const    archptr,
 
149
const ArchTorus2Dom * const domptr)
 
150
{
 
151
  return ((domptr->c[1][0] * archptr->c[0]) + domptr->c[0][0]); /* Return vertex number */
 
152
}
 
153
 
 
154
/* This function returns the terminal domain associated
 
155
** with the given terminal number in the architecture.
 
156
** It returns:
 
157
** - 0  : if label is valid and domain has been updated.
 
158
** - 1  : if label is invalid.
 
159
** - 2  : on error.
 
160
*/
 
161
 
 
162
int
 
163
archTorus2DomTerm (
 
164
const ArchTorus2 * const    archptr,
 
165
ArchTorus2Dom * const       domptr,
 
166
const ArchDomNum            domnum)
 
167
{
 
168
  if (domnum < (archptr->c[0] * archptr->c[1])) { /* If valid label */
 
169
    domptr->c[0][0] =                             /* Set the domain */
 
170
    domptr->c[0][1] = domnum % archptr->c[0];
 
171
    domptr->c[1][0] =
 
172
    domptr->c[1][1] = domnum / archptr->c[0];
 
173
 
 
174
    return (0);
 
175
  }
 
176
 
 
177
  return (1);                                     /* Cannot set domain */
 
178
}
 
179
 
 
180
/* This function returns the number of
 
181
** elements in the rectangular domain.
 
182
*/
 
183
 
 
184
Anum 
 
185
archTorus2DomSize (
 
186
const ArchTorus2 * const    archptr,
 
187
const ArchTorus2Dom * const domptr)
 
188
{
 
189
  return ((domptr->c[0][1] - domptr->c[0][0] + 1) *
 
190
          (domptr->c[1][1] - domptr->c[1][0] + 1));
 
191
}
 
192
 
 
193
/* This function returns the average
 
194
** distance between two rectangular
 
195
** domains (in fact the distance between
 
196
** the centers of the domains).
 
197
*/
 
198
 
 
199
Anum 
 
200
archTorus2DomDist (
 
201
const ArchTorus2 * const    archptr,
 
202
const ArchTorus2Dom * const dom0ptr,
 
203
const ArchTorus2Dom * const dom1ptr)
 
204
{
 
205
  Anum                dx, dy;
 
206
 
 
207
  dx = abs (dom0ptr->c[0][0] + dom0ptr->c[0][1] -
 
208
            dom1ptr->c[0][0] - dom1ptr->c[0][1]);
 
209
  dx = (dx > archptr->c[0])
 
210
       ? archptr->c[0] - (dx / 2)
 
211
       : (dx / 2);
 
212
 
 
213
  dy = abs (dom0ptr->c[1][0] + dom0ptr->c[1][1] -
 
214
            dom1ptr->c[1][0] - dom1ptr->c[1][1]);
 
215
  dy = (dy > archptr->c[1])
 
216
       ? archptr->c[1] - (dy / 2)
 
217
       : (dy / 2);
 
218
 
 
219
  return (dx + dy);
 
220
}
 
221
 
 
222
/* This function sets the biggest
 
223
** domain available for this
 
224
** architecture.
 
225
** It returns:
 
226
** - 0   : on success.
 
227
** - !0  : on error.
 
228
*/
 
229
 
 
230
int
 
231
archTorus2DomFrst (
 
232
const ArchTorus2 * const        archptr,
 
233
ArchTorus2Dom * restrict const  domptr)
 
234
{
 
235
  domptr->c[0][0] =
 
236
  domptr->c[1][0] = 0;
 
237
  domptr->c[0][1] = archptr->c[0] - 1;
 
238
  domptr->c[1][1] = archptr->c[1] - 1;
 
239
 
 
240
  return (0);
 
241
}
 
242
 
 
243
/* This routine reads domain information
 
244
** from the given stream.
 
245
** It returns:
 
246
** - 0   : on success.
 
247
** - !0  : on error.
 
248
*/
 
249
 
 
250
int
 
251
archTorus2DomLoad (
 
252
const ArchTorus2 * const        archptr,
 
253
ArchTorus2Dom * restrict const  domptr,
 
254
FILE * restrict const           stream)
 
255
{
 
256
  if (intLoad (stream, &domptr->c[0][0]) +
 
257
      intLoad (stream, &domptr->c[1][0]) +
 
258
      intLoad (stream, &domptr->c[0][1]) +
 
259
      intLoad (stream, &domptr->c[1][1]) != 4) {
 
260
    errorPrint ("archTorus2DomLoad: bad input");
 
261
    return     (1);
 
262
  }
 
263
 
 
264
  return (0);
 
265
}
 
266
 
 
267
/* This routine saves domain information
 
268
** to the given stream.
 
269
** - 0   : on success.
 
270
** - !0  : on error.
 
271
*/
 
272
 
 
273
int
 
274
archTorus2DomSave (
 
275
const ArchTorus2 * const    archptr,
 
276
const ArchTorus2Dom * const domptr,
 
277
FILE * restrict const       stream)
 
278
{
 
279
  if (fprintf (stream, "%ld %ld %ld %ld ",
 
280
               (long) domptr->c[0][0], (long) domptr->c[1][0],
 
281
               (long) domptr->c[0][1], (long) domptr->c[1][1]) == EOF) {
 
282
    errorPrint ("archTorus2DomSave: bad output");
 
283
    return     (1);
 
284
  }
 
285
 
 
286
  return (0);
 
287
}
 
288
 
 
289
/* This function tries to split a rectangular
 
290
** domain into two subdomains.
 
291
** It returns:
 
292
** - 0  : if bipartitioning succeeded.
 
293
** - 1  : if bipartitioning could not be performed.
 
294
** - 2  : on error.
 
295
*/
 
296
 
 
297
int
 
298
archTorus2DomBipart (
 
299
const ArchTorus2 * const        archptr,
 
300
const ArchTorus2Dom * const     domptr,
 
301
ArchTorus2Dom * restrict const  dom0ptr,
 
302
ArchTorus2Dom * restrict const  dom1ptr)
 
303
{
 
304
  if ((domptr->c[0][0] == domptr->c[0][1]) &&     /* Return if cannot bipartition more */
 
305
      (domptr->c[1][0] == domptr->c[1][1]))
 
306
    return (1);
 
307
 
 
308
  if ((domptr->c[0][1] - domptr->c[0][0]) >       /* Split domain in two along largest dimension */
 
309
      (domptr->c[1][1] - domptr->c[1][0])) {
 
310
    dom0ptr->c[0][0] = domptr->c[0][0];
 
311
    dom0ptr->c[0][1] = (domptr->c[0][0] + domptr->c[0][1]) / 2;
 
312
    dom1ptr->c[0][0] = dom0ptr->c[0][1] + 1;
 
313
    dom1ptr->c[0][1] = domptr->c[0][1];
 
314
    dom0ptr->c[1][0] = dom1ptr->c[1][0] = domptr->c[1][0];
 
315
    dom0ptr->c[1][1] = dom1ptr->c[1][1] = domptr->c[1][1];
 
316
  }
 
317
  else {
 
318
    dom0ptr->c[0][0] = dom1ptr->c[0][0] = domptr->c[0][0];
 
319
    dom0ptr->c[0][1] = dom1ptr->c[0][1] = domptr->c[0][1];
 
320
    dom0ptr->c[1][0] = domptr->c[1][0];
 
321
    dom0ptr->c[1][1] = (domptr->c[1][0] + domptr->c[1][1]) / 2;
 
322
    dom1ptr->c[1][0] = dom0ptr->c[1][1] + 1;
 
323
    dom1ptr->c[1][1] = domptr->c[1][1];
 
324
  }
 
325
 
 
326
  return (0);
 
327
}
 
328
 
 
329
/***********************************************/
 
330
/*                                             */
 
331
/* These are the 3-dimensional torus routines. */
 
332
/*                                             */
 
333
/***********************************************/
 
334
 
 
335
/* This routine loads the
 
336
** tridimensional torus architecture.
 
337
** It returns:
 
338
** - 0   : if the architecture has been successfully read.
 
339
** - !0  : on error.
 
340
*/
 
341
 
 
342
int
 
343
archTorus3ArchLoad (
 
344
ArchTorus3 * restrict const archptr,
 
345
FILE * restrict const       stream)
 
346
{
 
347
#ifdef SCOTCH_DEBUG_ARCH1
 
348
  if ((sizeof (ArchTorus3)    > sizeof (ArchDummy)) ||
 
349
      (sizeof (ArchTorus3Dom) > sizeof (ArchDomDummy))) {
 
350
    errorPrint ("archTorus3ArchLoad: invalid type specification");
 
351
    return     (1);
 
352
  }
 
353
#endif /* SCOTCH_DEBUG_ARCH1 */
 
354
 
 
355
  if ((intLoad (stream, &archptr->c[0]) +
 
356
       intLoad (stream, &archptr->c[1]) +
 
357
       intLoad (stream, &archptr->c[2]) != 3) ||
 
358
      (archptr->c[0] < 1) || (archptr->c[1] < 1) || (archptr->c[2] < 1)) {
 
359
    errorPrint ("archTorus3ArchLoad: bad input");
 
360
    return     (1);
 
361
  }
 
362
 
 
363
  return (0);
 
364
}
 
365
 
 
366
/* This routine saves the
 
367
** tridimensional torus architecture.
 
368
** It returns:
 
369
** - 0   : if the architecture has been successfully written.
 
370
** - !0  : on error.
 
371
*/
 
372
 
 
373
int
 
374
archTorus3ArchSave (
 
375
const ArchTorus3 * const    archptr,
 
376
FILE * restrict const       stream)
 
377
{
 
378
#ifdef SCOTCH_DEBUG_ARCH1
 
379
  if ((sizeof (ArchTorus3)    > sizeof (ArchDummy)) ||
 
380
      (sizeof (ArchTorus3Dom) > sizeof (ArchDomDummy))) {
 
381
    errorPrint ("archTorus3ArchSave: invalid type specification");
 
382
    return     (1);
 
383
  }
 
384
#endif /* SCOTCH_DEBUG_ARCH1 */
 
385
 
 
386
  if (fprintf (stream, "%ld %ld %ld ",
 
387
               (long) archptr->c[0], (long) archptr->c[1], (long) archptr->c[2]) == EOF) {
 
388
    errorPrint ("archTorus3ArchSave: bad output");
 
389
    return     (1);
 
390
  }
 
391
 
 
392
  return (0);
 
393
}
 
394
 
 
395
/* This function returns the smallest number
 
396
** of terminal domain included in the given
 
397
** domain.
 
398
*/
 
399
 
 
400
ArchDomNum
 
401
archTorus3DomNum (
 
402
const ArchTorus3 * const    archptr,
 
403
const ArchTorus3Dom * const domptr)
 
404
{
 
405
  return ((((domptr->c[2][0]  * archptr->c[1]) +  /* Return the vertex number */
 
406
             domptr->c[1][0]) * archptr->c[0]) +
 
407
             domptr->c[0][0]);
 
408
}
 
409
 
 
410
/* This function returns the terminal domain associated
 
411
** with the given terminal number in the architecture.
 
412
** It returns:
 
413
** - 0  : if label is valid and domain has been updated.
 
414
** - 1  : if label is invalid.
 
415
** - 2  : on error.
 
416
*/
 
417
 
 
418
int
 
419
archTorus3DomTerm (
 
420
const ArchTorus3 * const    archptr,
 
421
ArchTorus3Dom * const       domptr,
 
422
const ArchDomNum            domnum)
 
423
{
 
424
  if (domnum < (archptr->c[0] * archptr->c[1] * archptr->c[2])) { /* If valid label */
 
425
    domptr->c[0][0] =                             /* Set the domain                 */
 
426
    domptr->c[0][1] = domnum % archptr->c[0];
 
427
    domptr->c[1][0] =
 
428
    domptr->c[1][1] = (domnum / archptr->c[0]) % archptr->c[1];
 
429
    domptr->c[2][0] =
 
430
    domptr->c[2][1] = domnum / (archptr->c[0] * archptr->c[1]);
 
431
 
 
432
    return (0);
 
433
  }
 
434
 
 
435
  return (1);                                     /* Cannot set domain */
 
436
}
 
437
 
 
438
/* This function returns the number of
 
439
** elements in the cubic domain.
 
440
*/
 
441
 
 
442
Anum 
 
443
archTorus3DomSize (
 
444
const ArchTorus3 * const    archptr,
 
445
const ArchTorus3Dom * const domptr)
 
446
{
 
447
  return ((domptr->c[0][1] - domptr->c[0][0] + 1) *
 
448
          (domptr->c[1][1] - domptr->c[1][0] + 1) *
 
449
          (domptr->c[2][1] - domptr->c[2][0] + 1));
 
450
}
 
451
 
 
452
/* This function returns the average distance
 
453
** between two cubic domains (in fact the
 
454
** distance between the centers of the domains).
 
455
*/
 
456
 
 
457
Anum 
 
458
archTorus3DomDist (
 
459
const ArchTorus3 * const    archptr,
 
460
const ArchTorus3Dom * const dom0ptr,
 
461
const ArchTorus3Dom * const dom1ptr)
 
462
{
 
463
  Anum               dc, ds;
 
464
 
 
465
  dc = abs (dom0ptr->c[0][0] + dom0ptr->c[0][1] -
 
466
            dom1ptr->c[0][0] - dom1ptr->c[0][1]);
 
467
  ds = (dc > archptr->c[0])
 
468
       ? archptr->c[0] - (dc / 2)
 
469
       : (dc / 2);
 
470
 
 
471
  dc = abs (dom0ptr->c[1][0] + dom0ptr->c[1][1] -
 
472
            dom1ptr->c[1][0] - dom1ptr->c[1][1]);
 
473
  ds += (dc > archptr->c[1])
 
474
        ? archptr->c[1] - (dc / 2)
 
475
        : (dc / 2);
 
476
 
 
477
  dc = abs (dom0ptr->c[2][0] + dom0ptr->c[2][1] -
 
478
            dom1ptr->c[2][0] - dom1ptr->c[2][1]);
 
479
  ds += (dc > archptr->c[2])
 
480
        ? archptr->c[2] - (dc / 2)
 
481
        : (dc / 2);
 
482
 
 
483
  return (ds);
 
484
}
 
485
 
 
486
/* This function sets the biggest
 
487
** domain available for this
 
488
** architecture.
 
489
** It returns:
 
490
** - 0   : on success.
 
491
** - !0  : on error.
 
492
*/
 
493
 
 
494
int
 
495
archTorus3DomFrst (
 
496
const ArchTorus3 * const        archptr,
 
497
ArchTorus3Dom * restrict const  domptr)
 
498
{
 
499
  domptr->c[0][0] =
 
500
  domptr->c[1][0] =
 
501
  domptr->c[2][0] = 0;
 
502
  domptr->c[0][1] = archptr->c[0] - 1;
 
503
  domptr->c[1][1] = archptr->c[1] - 1;
 
504
  domptr->c[2][1] = archptr->c[2] - 1;
 
505
 
 
506
  return (0);
 
507
}
 
508
 
 
509
/* This routine reads domain information
 
510
** from the given stream.
 
511
** It returns:
 
512
** - 0   : on success.
 
513
** - !0  : on error.
 
514
*/
 
515
 
 
516
int
 
517
archTorus3DomLoad (
 
518
const ArchTorus3 * const        archptr,
 
519
ArchTorus3Dom * restrict const  domptr,
 
520
FILE * restrict const           stream)
 
521
{
 
522
  if (intLoad (stream, &domptr->c[0][0]) +
 
523
      intLoad (stream, &domptr->c[1][0]) +
 
524
      intLoad (stream, &domptr->c[2][0]) +
 
525
      intLoad (stream, &domptr->c[0][1]) +
 
526
      intLoad (stream, &domptr->c[1][1]) +
 
527
      intLoad (stream, &domptr->c[2][1]) != 6) {
 
528
    errorPrint ("archTorus3DomLoad: bad input");
 
529
    return     (1);
 
530
  }
 
531
 
 
532
  return (0);
 
533
}
 
534
 
 
535
/* This routine saves domain information
 
536
** to the given stream.
 
537
** It returns:
 
538
** - 0   : on success.
 
539
** - !0  : on error.
 
540
*/
 
541
 
 
542
int
 
543
archTorus3DomSave (
 
544
const ArchTorus3 * const    archptr,
 
545
const ArchTorus3Dom * const domptr,
 
546
FILE * restrict const       stream)
 
547
{
 
548
  if (fprintf (stream, "%ld %ld %ld %ld %ld %ld ",
 
549
               (long) domptr->c[0][0], (long) domptr->c[1][0], (long) domptr->c[2][0],
 
550
               (long) domptr->c[0][1], (long) domptr->c[1][1], (long) domptr->c[2][1]) == EOF) {
 
551
    errorPrint ("archTorus3DomSave: bad output");
 
552
    return     (1);
 
553
  }
 
554
 
 
555
  return (0);
 
556
}
 
557
 
 
558
/* This function tries to split a cubic
 
559
** domain into two subdomains.
 
560
** It returns:
 
561
** - 0  : if bipartitioning succeeded.
 
562
** - 1  : if bipartitioning could not be performed.
 
563
** - 2  : on error.
 
564
*/
 
565
 
 
566
int
 
567
archTorus3DomBipart (
 
568
const ArchTorus3 * const        archptr,
 
569
const ArchTorus3Dom * const     domptr,
 
570
ArchTorus3Dom * restrict const  dom0ptr,
 
571
ArchTorus3Dom * restrict const  dom1ptr)
 
572
{
 
573
  int                 i;
 
574
 
 
575
  if ((domptr->c[0][0] == domptr->c[0][1]) &&     /* Return if cannot bipartition more */
 
576
      (domptr->c[1][0] == domptr->c[1][1]) &&
 
577
      (domptr->c[2][0] == domptr->c[2][1]))
 
578
    return (1);
 
579
 
 
580
  i = ((domptr->c[1][1] - domptr->c[1][0]) >      /* Find largest dimension */
 
581
       (domptr->c[0][1] - domptr->c[0][0]))
 
582
    ? 1 : 0;
 
583
  if  ((domptr->c[2][1] - domptr->c[2][0]) >
 
584
       (domptr->c[i][1] - domptr->c[i][0]))
 
585
    i = 2;
 
586
 
 
587
  if (i == 0) {                                   /* Split domain in two along largest dimension */
 
588
    dom0ptr->c[0][0] = domptr->c[0][0];
 
589
    dom0ptr->c[0][1] = (domptr->c[0][0] + domptr->c[0][1]) / 2;
 
590
    dom1ptr->c[0][0] = dom0ptr->c[0][1] + 1;
 
591
    dom1ptr->c[0][1] = domptr->c[0][1];
 
592
 
 
593
    dom0ptr->c[1][0] = dom1ptr->c[1][0] = domptr->c[1][0];
 
594
    dom0ptr->c[1][1] = dom1ptr->c[1][1] = domptr->c[1][1];
 
595
 
 
596
    dom0ptr->c[2][0] = dom1ptr->c[2][0] = domptr->c[2][0];
 
597
    dom0ptr->c[2][1] = dom1ptr->c[2][1] = domptr->c[2][1];
 
598
  }
 
599
  else if (i == 1) {
 
600
    dom0ptr->c[0][0] = dom1ptr->c[0][0] = domptr->c[0][0];
 
601
    dom0ptr->c[0][1] = dom1ptr->c[0][1] = domptr->c[0][1];
 
602
 
 
603
    dom0ptr->c[1][0] = domptr->c[1][0];
 
604
    dom0ptr->c[1][1] = (domptr->c[1][0] + domptr->c[1][1]) / 2;
 
605
    dom1ptr->c[1][0] = dom0ptr->c[1][1] + 1;
 
606
    dom1ptr->c[1][1] = domptr->c[1][1];
 
607
 
 
608
    dom0ptr->c[2][0] = dom1ptr->c[2][0] = domptr->c[2][0];
 
609
    dom0ptr->c[2][1] = dom1ptr->c[2][1] = domptr->c[2][1];
 
610
  }
 
611
  else {
 
612
    dom0ptr->c[0][0] = dom1ptr->c[0][0] = domptr->c[0][0];
 
613
    dom0ptr->c[0][1] = dom1ptr->c[0][1] = domptr->c[0][1];
 
614
 
 
615
    dom0ptr->c[1][0] = dom1ptr->c[1][0] = domptr->c[1][0];
 
616
    dom0ptr->c[1][1] = dom1ptr->c[1][1] = domptr->c[1][1];
 
617
 
 
618
    dom0ptr->c[2][0] = domptr->c[2][0];
 
619
    dom0ptr->c[2][1] = (domptr->c[2][0] + domptr->c[2][1]) / 2;
 
620
    dom1ptr->c[2][0] = dom0ptr->c[2][1] + 1;
 
621
    dom1ptr->c[2][1] = domptr->c[2][1];
 
622
  }
 
623
 
 
624
  return (0);
 
625
}