/* MA2CE2.f -- translated by f2c (version 19960827).
   You must link the resulting object file with the libraries:
	-lf2c -lm   (in that order)
*/

#include "Data_f2c.h"

/* Subroutine */ int mma2ce2_(numdec, ndimen, nbsesp, ndimse, ndminu, ndminv, 
	ndguli, ndgvli, ndjacu, ndjacv, iordru, iordrv, nbpntu, nbpntv, 
	epsapr, sosotb, disotb, soditb, diditb, gssutb, gssvtb, xmaxju, 
	xmaxjv, vecerr, chpair, chimpr, patjac, errmax, errmoy, ndegpu, 
	ndegpv, itydec, iercod)
integer *numdec, *ndimen, *nbsesp, *ndimse, *ndminu, *ndminv, *ndguli, *
	ndgvli, *ndjacu, *ndjacv, *iordru, *iordrv, *nbpntu, *nbpntv;
doublereal *epsapr, *sosotb, *disotb, *soditb, *diditb, *gssutb, *gssvtb, *
	xmaxju, *xmaxjv, *vecerr, *chpair, *chimpr, *patjac, *errmax, *errmoy;
integer *ndegpu, *ndegpv, *itydec, *iercod;
{
    /* System generated locals */
    integer sosotb_dim1, sosotb_dim2, sosotb_offset, disotb_dim1, disotb_dim2,
	     disotb_offset, soditb_dim1, soditb_dim2, soditb_offset, 
	    diditb_dim1, diditb_dim2, diditb_offset, gssutb_dim1, gssvtb_dim1,
	     chpair_dim1, chpair_dim2, chpair_offset, chimpr_dim1, 
	    chimpr_dim2, chimpr_offset, patjac_dim1, patjac_dim2, 
	    patjac_offset, vecerr_dim1, vecerr_offset, i__1, i__2, i__3, i__4;

    /* Local variables */
    static logical ldbg;
    static integer idim, igsu, minu, minv, maxu, maxv, igsv;
    static doublereal vaux[3];
    static integer i2rdu, i2rdv, ndses, nd, ii, jj, kk, nu, nv;
    extern /* Subroutine */ int mma2er1_(), mma2er2_();
    static doublereal zu, zv;
    static integer nu1, nv1;
    extern /* Subroutine */ int mma2cfu_(), mma2cfv_(), mma2moy_();
    extern integer mnfndeb_();
    extern /* Subroutine */ int maermsg_(), mgenmsg_(), mgsomsg_(), mvriraz_()
	    ;
    extern doublereal mzsnorm_();








/* < */
/* **NOTICE */
/*  THIS SOFTWARE IS THE PROPERTY OF CISIGRAPH. */
/*  THIS CODE MUST NOT BE DISTRIBUTED OR COPIED WITHOUT THE PRIOR */
/*  WRITTEN PERMISSION OF CISIGRAPH AND IS ONLY TO BE USED ON THE */
/*  SITE WHERE IT IS INSTALLED BY CISIGRAPH */
/* **NOTICE */

/* ********************************************************************** 
*/

/*     FONCTION : */
/*     ---------- */
/*     Calcul des coefficients de l' approximation polynomiale de degre */
/*     (NDJACU,NDJACV) d'une fonction F(u,v) quelconque, a partir de sa */
/*     discretisation sur les racines du polynome de Legendre de degre */
/*     NBPNTU en U et NBPNTV en V. */

/*     MOTS CLES : */
/*     ----------- */
/*     TOUS,AB_SPECIFI::FONCTION&,APPROXIMATION,&COEFFICIENT,&POLYNOME */

/*     ARGUMENTS D'ENTREE : */
/*     ------------------ */
/*   NUMDEC: Indique si on PEUT decouper encore la fonction F(u,v). */
/*           = 5, On PEUT couper en U ou en V ou dans les 2 sens a la */
/*                fois. */
/*           = 4, On PEUT couper en U ou en V MAIS PAS dans les 2 sens */
/*                a la fois (decoupe en V favorisee). */
/*           = 3, On PEUT couper en U ou en V MAIS PAS dans les 2 sens */
/*                a la fois (decoupe en U favorisee). */
/*           = 2, on ne PEUT couper qu'en V (i.e. inserer un parametre */
/*                de decoupe Vj). */
/*           = 1, on ne PEUT couper qu'en U (i.e. inserer un parametre */
/*                de decoupe Ui). */
/*           = 0, on ne PEUT plus rien couper */
/*   NDIMEN: Dimension totale de l'espace */
/*   NBSESP: Nbre de sous-espaces independant sur lesquels on calcule */
/*           les erreurs. */
/*   NDIMSE: Table des dimensions de chacun des sous-espaces. */
/*   NDMINU: Degre minimum en U a conserver pour l'approximation. */
/*   NDMINV: Degre minimum en V a conserver pour l'approximation. */
/*   NDGULI: Limite du degre en U de la solution. */
/*   NDGVLI: Limite du degre en V de la solution. */
/*   NDJACU: Degre maxi du polynome d' approximation en U. La */
/*           representation dans la base orthogonale part du degre */
/*           0 au degre NDJACU-2*(IORDRU+1). La base polynomiale est */
/*           la base de Jacobi d' ordre -1 (Legendre), 0, 1 ou 2. */
/*           On doit avoir 2*IORDRU+1 <= NDMINU <= NDGULI < NDJACU */
/*   NDJACV: Degre maxi du polynome d' approximation en V. La */
/*           representation dans la base orthogonale part du degre */
/*           0 au degre NDJACV-2*(IORDRV+1). La base polynomiale est */
/*           la base de Jacobi d' ordre -1 (Legendre), 0, 1 ou 2 */
/*           On doit avoir 2*IORDRV+1 <= NDMINV <= NDGVLI < NDJACV */
/*   IORDRU: Ordre de la base de Jacobi (-1,0,1 ou 2) en U. Correspond */
/*           a pas de contraintes, contraintes C0, C1 ou C2. */
/*   IORDRV: Ordre de la base de Jacobi (-1,0,1 ou 2) en V. Correspond */
/*           a pas de contraintes, contraintes C0, C1 ou C2. */
/*   NBPNTU: Degre du polynome de Legendre sur les racines duquel */
/*           sont calcules les coefficients d' integration suivant u */
/*           par la methode de Gauss. On doit avoir NBPNTU = 30, 40, */
/*           50 ou 61 et NDJACU-2*(IORDRU+1) < NBPNTU. */
/*   NBPNTV: Degre du polynome de Legendre sur les racines duquel */
/*           sont calcules les coefficients d' integration suivant v */
/*           par la methode de Gauss. On doit avoir NBPNTV = 30, 40, */
/*           50 ou 61 et NDJACV-2*(IORDRV+1) < NBPNTV. */
/*   EPSAPR: Table des NBSESP tolerances imposees sur chacun des */
/*           sous-espaces. */
/*   SOSOTB: Tableau de F(ui,vj) + F(ui,-vj) + F(-ui,vj) + F(-ui,-vj) */
/*           avec ui et vj racines positives du polynome de Legendre */
/*           de degre NBPNTU et NBPNTV respectivement. De plus, */
/*           le tableau SOSOTB(0,j) contient F(0,vj) + F(0,-vj), */
/*           le tableau SOSOTB(i,0) contient F(ui,0) + F(-ui,0) et */
/*           SOSOTB(0,0) contient F(0,0). */
/*   DISOTB: Tableau de F(ui,vj) + F(ui,-vj) - F(-ui,vj) - F(-ui,-vj) */
/*           avec ui et vj racines positives du polynome de Legendre */
/*           de degre NBPNTU et NBPNTV respectivement. */
/*   SODITB: Tableau de F(ui,vj) - F(ui,-vj) + F(-ui,vj) - F(-ui,-vj) */
/*           avec ui et vj racines positives du polynome de Legendre */
/*           de degre NBPNTU et NBPNTV respectivement. */
/*   DIDITB: Tableau de F(ui,vj) - F(ui,-vj) - F(-ui,vj) + F(-ui,-vj) */
/*           avec ui et vj racines positives du polynome de Legendre */
/*           de degre NBPNTU et NBPNTV respectivement. De plus, */
/*           le tableau DIDITB(0,j) contient F(0,vj) - F(0,-vj), */
/*           et le tableau DIDITB(i,0) contient F(ui,0) - F(-ui,0). */
/*   GSSUTB: Table des coefficients d' integration par la methode de */
/*           Gauss suivant U: i varie de 0 a NBPNTU/2 et k varie de 0 a */
/*           NDJACU-2*(IORDRU+1). */
/*   GSSVTB: Table des coefficients d' integration par la methode de */
/*           Gauss suivant V: i varie de 0 a NBPNTV/2 et k varie de 0 a */
/*           NDJACV-2*(IORDRV+1). */
/*   XMAXJU: Valeur maximale des polynomes de Jacobi d'ordre IORDRU, */
/*           du degre 0 au degre NDJACU - 2*(IORDRU+1) */
/*   XMAXJV: Valeur maximale des polynomes de Jacobi d'ordre IORDRV, */
/*           du degre 0 au degre NDJACV - 2*(IORDRV+1) */

/*     ARGUMENTS DE SORTIE : */
/*     ------------------- */
/*   VECERR: Tableau auxiliaire. */
/*   CHPAIR: Tableau auxiliaire de termes lies au degre NDJACU en U */
/*           pour calculer les coeff. de l'approximation de degre PAIR */
/*           en V. */
/*   CHIMPR: Tableau auxiliaire de termes lies au degre NDJACU en U */
/*           pour calculer les coeff. de l'approximation de degre IMPAIR 
*/
/*           en V. */
/*   PATJAC: Table des coefficients du polynome P(u,v) d' approximation */
/*           de F(u,v) avec eventuellement prise en compte des */
/*           contraintes. P(u,v) est de degre (NDJACU,NDJACV). */
/*           Ce tableau ne contient les coeff que si ITYDEC = 0. */
/*   ERRMAX: Pour 1<=i<=NBSESP, ERRMAX(i) contient les erreurs maxi */
/*           sur chacun des sous-espaces SI ITYDEC = 0. */
/*   ERRMOY: Contient les erreurs moyennes pour chacun des NBSESP */
/*           sous-espaces SI ITYDEC = 0. */
/*   NDEGPU: Degre en U pour le carreau PATJAC. Valable si ITYDEC=0. */
/*   NDEGPV: Degre en V pour le carreau PATJAC. Valable si ITYDEC=0. */
/*   ITYDEC: Indique si on DOIT decouper encore la fonction F(u,v). */
/*           = 0, on ne DOIT plus rien couper, PATJAC est OK ou alors */
/*                NUMDEC etant egal a zero, on ne pouvait plus couper. */
/*           = 1, on ne DOIT couper qu'en U (i.e. inserer un parametre */
/*                de decoupe Ui). */
/*           = 2, on ne DOIT couper qu'en V (i.e. inserer un parametre */
/*                de decoupe Vj). */
/*           = 3, On DOIT couper en U ET en V a la fois. */
/*   IERCOD: Code d'erreur. */
/*           =  0, Eh bien tout va tres bien. */
/*           = -1, On a une solution, la meilleure possible, mais la */
/*                 tolerance utilisateur n'est pas satisfaite (3*helas) */
/*           =  1, Entrees incoherentes. */

/*     COMMONS UTILISES   : */
/*     ---------------- */

/*     REFERENCES APPELEES   : */
/*     ----------------------- */

/*     DESCRIPTION/REMARQUES/LIMITATIONS : */
/*     ----------------------------------- */

/* $    HISTORIQUE DES MODIFICATIONS   : */
/*     -------------------------------- */
/*     07-02-1992: RBD; Gestion des cas MINU>MAXU et/ou MINV>MAXV */
/*     05-02-1992: RBD: Prise en compte decalages de CHPAIR et CHIMPR */
/*     22-01-1992: RBD; Creation d'apres MA2CF2. */
/* > */
/* ********************************************************************** 
*/
/*   Le nom de la routine */


/* --------------------------- Initialisations -------------------------- 
*/

    /* Parameter adjustments */
    vecerr_dim1 = *ndimen;
    vecerr_offset = vecerr_dim1 + 1;
    vecerr -= vecerr_offset;
    --errmoy;
    --errmax;
    --epsapr;
    --ndimse;
    patjac_dim1 = *ndjacu + 1;
    patjac_dim2 = *ndjacv + 1;
    patjac_offset = patjac_dim1 * patjac_dim2;
    patjac -= patjac_offset;
    gssutb_dim1 = *nbpntu / 2 + 1;
    chimpr_dim1 = *nbpntv / 2;
    chimpr_dim2 = *ndjacu - ((*iordru + 1) << 1) + 1;
    chimpr_offset = chimpr_dim1 * chimpr_dim2 + 1;
    chimpr -= chimpr_offset;
    chpair_dim1 = *nbpntv / 2 + 1;
    chpair_dim2 = *ndjacu - ((*iordru + 1) << 1) + 1;
    chpair_offset = chpair_dim1 * chpair_dim2;
    chpair -= chpair_offset;
    gssvtb_dim1 = *nbpntv / 2 + 1;
    diditb_dim1 = *nbpntu / 2 + 1;
    diditb_dim2 = *nbpntv / 2 + 1;
    diditb_offset = diditb_dim1 * diditb_dim2;
    diditb -= diditb_offset;
    soditb_dim1 = *nbpntu / 2;
    soditb_dim2 = *nbpntv / 2;
    soditb_offset = soditb_dim1 * (soditb_dim2 + 1) + 1;
    soditb -= soditb_offset;
    disotb_dim1 = *nbpntu / 2;
    disotb_dim2 = *nbpntv / 2;
    disotb_offset = disotb_dim1 * (disotb_dim2 + 1) + 1;
    disotb -= disotb_offset;
    sosotb_dim1 = *nbpntu / 2 + 1;
    sosotb_dim2 = *nbpntv / 2 + 1;
    sosotb_offset = sosotb_dim1 * sosotb_dim2;
    sosotb -= sosotb_offset;

    /* Function Body */
    ldbg = mnfndeb_() >= 3;
    if (ldbg) {
	mgenmsg_("MMA2CE2", 7L);
    }
/* --> A priori tout va bien */
    *iercod = 0;
/* --> test des entrees */
    if (*numdec < 0 || *numdec > 5) {
	goto L9001;
    }
    if ((*iordru << 1) + 1 > *ndminu) {
	goto L9001;
    }
    if (*ndminu > *ndguli) {
	goto L9001;
    }
    if (*ndguli >= *ndjacu) {
	goto L9001;
    }
    if ((*iordrv << 1) + 1 > *ndminv) {
	goto L9001;
    }
    if (*ndminv > *ndgvli) {
	goto L9001;
    }
    if (*ndgvli >= *ndjacv) {
	goto L9001;
    }
/* --> A priori, pas de decoupes a faire. */
    *itydec = 0;
/* --> Degres mini a retourner: NDMINU,NDMINV */
    *ndegpu = *ndminu;
    *ndegpv = *ndminv;
/* --> Pour le moment, les erreurs max sont nulles */
    mvriraz_(nbsesp, &errmax[1]);
    nd = *ndimen << 2;
    mvriraz_(&nd, &vecerr[vecerr_offset]);
/* --> et le carreau aussi. */
    nd = (*ndjacu + 1) * (*ndjacv + 1) * *ndimen;
    mvriraz_(&nd, &patjac[patjac_offset]);

    i2rdu = (*iordru + 1) << 1;
    i2rdv = (*iordrv + 1) << 1;

/* ********************************************************************** 
*/
/* -------------------- ICI, ON PEUT ENCORE DECOUPER -------------------- 
*/
/* ********************************************************************** 
*/

    if (*numdec > 0 && *numdec <= 5) {

/* ******************************************************************
**** */
/* ---------------------- Calcul des coeff de la zone 4 -------------
---- */

	minu = *ndguli + 1;
	maxu = *ndjacu;
	minv = *ndgvli + 1;
	maxv = *ndjacv;
	if (minu > maxu) {
	    goto L9001;
	}
	if (minv > maxv) {
	    goto L9001;
	}

/* ---------------- Calcul des termes lies au degre en U ------------
---- */

	i__1 = *ndimen;
	for (nd = 1; nd <= i__1; ++nd) {
	    i__2 = maxu;
	    for (kk = minu; kk <= i__2; ++kk) {
		igsu = kk - i2rdu;
		mma2cfu_(&kk, nbpntu, nbpntv, &sosotb[nd * sosotb_dim2 * 
			sosotb_dim1], &disotb[(nd * disotb_dim2 + 1) * 
			disotb_dim1 + 1], &soditb[(nd * soditb_dim2 + 1) * 
			soditb_dim1 + 1], &diditb[nd * diditb_dim2 * 
			diditb_dim1], &gssutb[igsu * gssutb_dim1], &chpair[(
			igsu + nd * chpair_dim2) * chpair_dim1], &chimpr[(
			igsu + nd * chimpr_dim2) * chimpr_dim1 + 1]);
/* L110: */
	    }
/* L100: */
	}

/* ------------------- Calcul des coefficients de PATJAC ------------
---- */

	igsu = minu - i2rdu;
	i__1 = maxv;
	for (jj = minv; jj <= i__1; ++jj) {
	    igsv = jj - i2rdv;
	    i__2 = *ndimen;
	    for (nd = 1; nd <= i__2; ++nd) {
		mma2cfv_(&jj, &minu, &maxu, nbpntv, &gssvtb[igsv * 
			gssvtb_dim1], &chpair[(igsu + nd * chpair_dim2) * 
			chpair_dim1], &chimpr[(igsu + nd * chimpr_dim2) * 
			chimpr_dim1 + 1], &patjac[minu + (jj + nd * 
			patjac_dim2) * patjac_dim1]);
/* L130: */
	    }

/* ----- Contribution des termes calcules a l'erreur d'approximati
on ---- */
/* pour les termes (I,J) avec MINU <= I <= MAXU, J fixe. */

	    idim = 1;
	    i__2 = *nbsesp;
	    for (nd = 1; nd <= i__2; ++nd) {
		ndses = ndimse[nd];
		mma2er1_(ndjacu, ndjacv, &ndses, &minu, &maxu, &jj, &jj, 
			iordru, iordrv, xmaxju, xmaxjv, &patjac[idim * 
			patjac_dim2 * patjac_dim1], &vecerr[vecerr_dim1 + 1], 
			&vecerr[nd + (vecerr_dim1 << 2)]);
		if (vecerr[nd + (vecerr_dim1 << 2)] > epsapr[nd]) {
		    goto L9300;
		}
		idim += ndses;
/* L140: */
	    }
/* L120: */
	}

/* ******************************************************************
**** */
/* ---------------------- Calcul des coeff de la zone 2 -------------
---- */

	minu = (*iordru + 1) << 1;
	maxu = *ndguli;
	minv = *ndgvli + 1;
	maxv = *ndjacv;

/* --> Si la zone 2 est vide, on passe a la zone 3. */
/*    VECERR(ND,2) a deja ete mis a zero. */
	if (minu > maxu) {
	    goto L300;
	}

/* ---------------- Calcul des termes lies au degre en U ------------
---- */

	i__1 = *ndimen;
	for (nd = 1; nd <= i__1; ++nd) {
	    i__2 = maxu;
	    for (kk = minu; kk <= i__2; ++kk) {
		igsu = kk - i2rdu;
		mma2cfu_(&kk, nbpntu, nbpntv, &sosotb[nd * sosotb_dim2 * 
			sosotb_dim1], &disotb[(nd * disotb_dim2 + 1) * 
			disotb_dim1 + 1], &soditb[(nd * soditb_dim2 + 1) * 
			soditb_dim1 + 1], &diditb[nd * diditb_dim2 * 
			diditb_dim1], &gssutb[igsu * gssutb_dim1], &chpair[(
			igsu + nd * chpair_dim2) * chpair_dim1], &chimpr[(
			igsu + nd * chimpr_dim2) * chimpr_dim1 + 1]);
/* L210: */
	    }
/* L200: */
	}

/* ------------------- Calcul des coefficients de PATJAC ------------
---- */

	igsu = minu - i2rdu;
	i__1 = maxv;
	for (jj = minv; jj <= i__1; ++jj) {
	    igsv = jj - i2rdv;
	    i__2 = *ndimen;
	    for (nd = 1; nd <= i__2; ++nd) {
		mma2cfv_(&jj, &minu, &maxu, nbpntv, &gssvtb[igsv * 
			gssvtb_dim1], &chpair[(igsu + nd * chpair_dim2) * 
			chpair_dim1], &chimpr[(igsu + nd * chimpr_dim2) * 
			chimpr_dim1 + 1], &patjac[minu + (jj + nd * 
			patjac_dim2) * patjac_dim1]);
/* L230: */
	    }
/* L220: */
	}

/* ----- Contribution des termes calcules a l'erreur d'approximation 
---- */
/* pour les termes (I,J) avec MINU <= I <= MAXU, MINV <= J <= MAXV */

	idim = 1;
	i__1 = *nbsesp;
	for (nd = 1; nd <= i__1; ++nd) {
	    ndses = ndimse[nd];
	    mma2er1_(ndjacu, ndjacv, &ndses, &minu, &maxu, &minv, &maxv, 
		    iordru, iordrv, xmaxju, xmaxjv, &patjac[idim * 
		    patjac_dim2 * patjac_dim1], &vecerr[vecerr_dim1 + 1], &
		    vecerr[nd + (vecerr_dim1 << 1)]);
	    idim += ndses;
/* L240: */
	}

/* ******************************************************************
**** */
/* ---------------------- Calcul des coeff de la zone 3 -------------
---- */

L300:
	minu = *ndguli + 1;
	maxu = *ndjacu;
	minv = (*iordrv + 1) << 1;
	maxv = *ndgvli;

/* --> Si la zone 3 est vide, on passe au test de decoupe. */
/*    VECERR(ND,3) a deja ete mis a zero */
	if (minv > maxv) {
	    goto L400;
	}

/* ----------- Les termes lies au degre en U sont deja calcules -----
---- */
/* ------------------- Calcul des coefficients de PATJAC ------------
---- */

	igsu = minu - i2rdu;
	i__1 = maxv;
	for (jj = minv; jj <= i__1; ++jj) {
	    igsv = jj - i2rdv;
	    i__2 = *ndimen;
	    for (nd = 1; nd <= i__2; ++nd) {
		mma2cfv_(&jj, &minu, &maxu, nbpntv, &gssvtb[igsv * 
			gssvtb_dim1], &chpair[(igsu + nd * chpair_dim2) * 
			chpair_dim1], &chimpr[(igsu + nd * chimpr_dim2) * 
			chimpr_dim1 + 1], &patjac[minu + (jj + nd * 
			patjac_dim2) * patjac_dim1]);
/* L330: */
	    }
/* L320: */
	}

/* ----- Contribution des termes calcules a l'erreur d'approximation 
---- */
/* pour les termes (I,J) avec MINU <= I <= MAXU, MINV <= J <= MAXV. */

	idim = 1;
	i__1 = *nbsesp;
	for (nd = 1; nd <= i__1; ++nd) {
	    ndses = ndimse[nd];
	    mma2er1_(ndjacu, ndjacv, &ndses, &minu, &maxu, &minv, &maxv, 
		    iordru, iordrv, xmaxju, xmaxjv, &patjac[idim * 
		    patjac_dim2 * patjac_dim1], &vecerr[vecerr_dim1 + 1], &
		    vecerr[nd + vecerr_dim1 * 3]);
	    idim += ndses;
/* L340: */
	}

/* ******************************************************************
**** */
/* --------------------------- Tests de decoupe ---------------------
---- */

L400:
	i__1 = *nbsesp;
	for (nd = 1; nd <= i__1; ++nd) {
	    vaux[0] = vecerr[nd + (vecerr_dim1 << 1)];
	    vaux[1] = vecerr[nd + (vecerr_dim1 << 2)];
	    vaux[2] = vecerr[nd + vecerr_dim1 * 3];
	    ii = 3;
	    errmax[nd] = mzsnorm_(&ii, vaux);
	    if (errmax[nd] > epsapr[nd]) {
		ii = 2;
		zv = mzsnorm_(&ii, vaux);
		zu = mzsnorm_(&ii, &vaux[1]);
		if (zu > epsapr[nd] && zv > epsapr[nd]) {
		    goto L9300;
		}
		if (zu > zv) {
		    goto L9100;
		} else {
		    goto L9200;
		}
	    }
/* L410: */
	}

/* ******************************************************************
**** */
/* --- OK, le carreau est valable, on calcule les coeff de la zone 1 
---- */

	minu = (*iordru + 1) << 1;
	maxu = *ndguli;
	minv = (*iordrv + 1) << 1;
	maxv = *ndgvli;

/* --> Si la zone 1 est vide, on passe au calcul de l'erreur Maxi et 
*/
/*    Moyenne. */
	if (minu > maxu || minv > maxv) {
	    goto L600;
	}

/* ----------- Les termes lies au degre en U sont deja calcules -----
---- */
/* ------------------- Calcul des coefficients de PATJAC ------------
---- */

	igsu = minu - i2rdu;
	i__1 = maxv;
	for (jj = minv; jj <= i__1; ++jj) {
	    igsv = jj - i2rdv;
	    i__2 = *ndimen;
	    for (nd = 1; nd <= i__2; ++nd) {
		mma2cfv_(&jj, &minu, &maxu, nbpntv, &gssvtb[igsv * 
			gssvtb_dim1], &chpair[(igsu + nd * chpair_dim2) * 
			chpair_dim1], &chimpr[(igsu + nd * chimpr_dim2) * 
			chimpr_dim1 + 1], &patjac[minu + (jj + nd * 
			patjac_dim2) * patjac_dim1]);
/* L530: */
	    }
/* L520: */
	}

/* --------------- Maintenant, on baisse le degre au maximum --------
---- */

L600:
/* Computing MAX */
	i__1 = 1, i__2 = (*iordru << 1) + 1, i__1 = max(i__1,i__2);
	minu = max(i__1,*ndminu);
	maxu = *ndguli;
/* Computing MAX */
	i__1 = 1, i__2 = (*iordrv << 1) + 1, i__1 = max(i__1,i__2);
	minv = max(i__1,*ndminv);
	maxv = *ndgvli;
	idim = 1;
	i__1 = *nbsesp;
	for (nd = 1; nd <= i__1; ++nd) {
	    ndses = ndimse[nd];
	    if (maxu >= (*iordru + 1) << 1 && maxv >= (*iordrv + 1) << 1) {
		mma2er2_(ndjacu, ndjacv, &ndses, &minu, &maxu, &minv, &maxv, 
			iordru, iordrv, xmaxju, xmaxjv, &patjac[idim * 
			patjac_dim2 * patjac_dim1], &epsapr[nd], &vecerr[
			vecerr_dim1 + 1], &errmax[nd], &nu, &nv);
	    } else {
		nu = maxu;
		nv = maxv;
	    }
	    nu1 = nu + 1;
	    nv1 = nv + 1;

/* --> Calcul de l'erreur moyenne. */
	    mma2moy_(ndjacu, ndjacv, &ndses, &nu1, ndjacu, &nv1, ndjacv, 
		    iordru, iordrv, &patjac[idim * patjac_dim2 * patjac_dim1],
		     &errmoy[nd]);

/* --> Mise a 0.D0 des coeff ecartes. */
	    i__2 = idim + ndses - 1;
	    for (ii = idim; ii <= i__2; ++ii) {
		i__3 = *ndjacv;
		for (jj = nv1; jj <= i__3; ++jj) {
		    i__4 = *ndjacu;
		    for (kk = nu1; kk <= i__4; ++kk) {
			patjac[kk + (jj + ii * patjac_dim2) * patjac_dim1] = 
				0.;
/* L640: */
		    }
/* L630: */
		}
/* L620: */
	    }

/* --> Recup des nbre de coeff de l'approximation. */
	    *ndegpu = max(*ndegpu,nu);
	    *ndegpv = max(*ndegpv,nv);
	    idim += ndses;
/* L610: */
	}

/* ******************************************************************
**** */
/* -------------------- LA, ON NE PEUT PLUS DECOUPER ----------------
---- */
/* ******************************************************************
**** */

    } else {
	minu = (*iordru + 1) << 1;
	maxu = *ndjacu;
	minv = (*iordrv + 1) << 1;
	maxv = *ndjacv;

/* ---------------- Calcul des termes lies au degre en U ------------
---- */

	i__1 = *ndimen;
	for (nd = 1; nd <= i__1; ++nd) {
	    i__2 = maxu;
	    for (kk = minu; kk <= i__2; ++kk) {
		igsu = kk - i2rdu;
		mma2cfu_(&kk, nbpntu, nbpntv, &sosotb[nd * sosotb_dim2 * 
			sosotb_dim1], &disotb[(nd * disotb_dim2 + 1) * 
			disotb_dim1 + 1], &soditb[(nd * soditb_dim2 + 1) * 
			soditb_dim1 + 1], &diditb[nd * diditb_dim2 * 
			diditb_dim1], &gssutb[igsu * gssutb_dim1], &chpair[(
			igsu + nd * chpair_dim2) * chpair_dim1], &chimpr[(
			igsu + nd * chimpr_dim2) * chimpr_dim1 + 1]);
/* L710: */
	    }

/* ---------------------- Calcul de tous les coefficients -------
-------- */

	    igsu = minu - i2rdu;
	    i__2 = maxv;
	    for (jj = minv; jj <= i__2; ++jj) {
		igsv = jj - i2rdv;
		mma2cfv_(&jj, &minu, &maxu, nbpntv, &gssvtb[igsv * 
			gssvtb_dim1], &chpair[(igsu + nd * chpair_dim2) * 
			chpair_dim1], &chimpr[(igsu + nd * chimpr_dim2) * 
			chimpr_dim1 + 1], &patjac[minu + (jj + nd * 
			patjac_dim2) * patjac_dim1]);
/* L720: */
	    }
/* L700: */
	}

/* ----- Contribution des termes calcules a l'erreur d'approximation 
---- */
/* pour les termes (I,J) avec MINU <= I <= MAXU, MINV <= J <= MAXV */

	idim = 1;
	i__1 = *nbsesp;
	for (nd = 1; nd <= i__1; ++nd) {
	    ndses = ndimse[nd];
	    minu = (*iordru + 1) << 1;
	    maxu = *ndjacu;
	    minv = *ndgvli + 1;
	    maxv = *ndjacv;
	    mma2er1_(ndjacu, ndjacv, &ndses, &minu, &maxu, &minv, &maxv, 
		    iordru, iordrv, xmaxju, xmaxjv, &patjac[idim * 
		    patjac_dim2 * patjac_dim1], &vecerr[vecerr_dim1 + 1], &
		    errmax[nd]);
	    minu = *ndguli + 1;
	    maxu = *ndjacu;
	    minv = (*iordrv + 1) << 1;
	    maxv = *ndgvli;
	    if (minv <= maxv) {
		mma2er1_(ndjacu, ndjacv, &ndses, &minu, &maxu, &minv, &maxv, 
			iordru, iordrv, xmaxju, xmaxjv, &patjac[idim * 
			patjac_dim2 * patjac_dim1], &vecerr[vecerr_dim1 + 1], 
			&errmax[nd]);
	    }

/* ---------------------------- Si ERRMAX > EPSAPR, stop --------
-------- */

	    if (errmax[nd] > epsapr[nd]) {
		*iercod = -1;
		nu = *ndguli;
		nv = *ndgvli;

/* ------------- Sinon, on essaie d'enlever encore des coeff 
------------ */

	    } else {
/* Computing MAX */
		i__2 = 1, i__3 = (*iordru << 1) + 1, i__2 = max(i__2,i__3);
		minu = max(i__2,*ndminu);
		maxu = *ndguli;
/* Computing MAX */
		i__2 = 1, i__3 = (*iordrv << 1) + 1, i__2 = max(i__2,i__3);
		minv = max(i__2,*ndminv);
		maxv = *ndgvli;
		if (maxu >= (*iordru + 1) << 1 && maxv >= (*iordrv + 1) << 1) {
		    mma2er2_(ndjacu, ndjacv, &ndses, &minu, &maxu, &minv, &
			    maxv, iordru, iordrv, xmaxju, xmaxjv, &patjac[
			    idim * patjac_dim2 * patjac_dim1], &epsapr[nd], &
			    vecerr[vecerr_dim1 + 1], &errmax[nd], &nu, &nv);
		} else {
		    nu = maxu;
		    nv = maxv;
		}
	    }

/* --------------------- Calcul de l'erreur moyenne -------------
-------- */

	    nu1 = nu + 1;
	    nv1 = nv + 1;
	    mma2moy_(ndjacu, ndjacv, &ndses, &nu1, ndjacu, &nv1, ndjacv, 
		    iordru, iordrv, &patjac[idim * patjac_dim2 * patjac_dim1],
		     &errmoy[nd]);

/* --------------------- Mise a 0.D0 des coeff ecartes ----------
-------- */

	    i__2 = idim + ndses - 1;
	    for (ii = idim; ii <= i__2; ++ii) {
		i__3 = *ndjacv;
		for (jj = nv1; jj <= i__3; ++jj) {
		    i__4 = *ndjacu;
		    for (kk = nu1; kk <= i__4; ++kk) {
			patjac[kk + (jj + ii * patjac_dim2) * patjac_dim1] = 
				0.;
/* L760: */
		    }
/* L750: */
		}
/* L740: */
	    }

/* --------------- Recup des nbre de coeff de l'approximation ---
-------- */

	    *ndegpu = max(*ndegpu,nu);
	    *ndegpv = max(*ndegpv,nv);
	    idim += ndses;
/* L730: */
	}
    }

    goto L9999;

/* ------------------------------ The end ------------------------------- 
*/
/* --> Erreur dans les entrees */
L9001:
    *iercod = 1;
    goto L9999;

/* --------- Gestion des decoupes, ici doit avoir 0 < NUMDEC <= 5 ------- 
*/

/* --> Ici on peut et on doit couper, on choisit en U si c'est possible */
L9100:
    if (*numdec <= 0 || *numdec > 5) {
	goto L9001;
    }
    if (*numdec != 2) {
	*itydec = 1;
    } else {
	*itydec = 2;
    }
    goto L9999;
/* --> Ici on peut et on doit couper, on choisit en V si c'est possible */
L9200:
    if (*numdec <= 0 || *numdec > 5) {
	goto L9001;
    }
    if (*numdec != 1) {
	*itydec = 2;
    } else {
	*itydec = 1;
    }
    goto L9999;
/* --> Ici on peut et on doit couper, on choisit en 4 si c'est possible */
L9300:
    if (*numdec <= 0 || *numdec > 5) {
	goto L9001;
    }
    if (*numdec == 5) {
	*itydec = 3;
    } else if (*numdec == 2 || *numdec == 4) {
	*itydec = 2;
    } else if (*numdec == 1 || *numdec == 3) {
	*itydec = 1;
    } else {
	goto L9001;
    }
    goto L9999;

L9999:
    maermsg_("MMA2CE2", iercod, 7L);
    if (ldbg) {
	mgsomsg_("MMA2CE2", 7L);
    }
    return 0;
} /* mma2ce2_ */

