void frictionContact3D_SOCLCP(FrictionContactProblem* problem, double *reaction, double *velocity, int* info, SolverOptions* options) { /* int and double parameters */ int* iparam = options->iparam; double* dparam = options->dparam; /* Number of contacts */ int nc = problem->numberOfContacts; /* Tolerance */ double tolerance = dparam[0]; if (options->numberOfInternalSolvers < 1) { numericsError("frictionContact3D_SOCLCP", "The SOCLCP for FrictionContactProblem needs options for the internal solvers, options[0].numberOfInternalSolvers should be >1"); } SolverOptions * internalsolver_options = options->internalSolvers; if (verbose > 0) { printf("Local solver data :"); printSolverOptions(internalsolver_options); } /***** Fixed Point Iterations *****/ double error = 1.; /* Current error */ soclcp_InternalSolverPtr internalsolver; SecondOrderConeLinearComplementarityProblem* soclcp = (SecondOrderConeLinearComplementarityProblem *)malloc(sizeof(SecondOrderConeLinearComplementarityProblem)); soclcp->n = problem->numberOfContacts * problem->dimension; soclcp->nc= problem->numberOfContacts; soclcp->M = problem-> M; soclcp->q = (double *) malloc(soclcp->n * sizeof(double)); soclcp->mu = problem->mu; soclcp->coneIndex = (unsigned int *) malloc((soclcp->nc+1) * sizeof(unsigned int)); for (int i=0; i < soclcp->n; i++) { soclcp->q[i]=problem->q[i]; } for (int i=0; i < soclcp->nc+1; i++) { soclcp->coneIndex[i] = 3*i; } if (internalsolver_options->solverId == SICONOS_SOCLCP_NSGS) { if (verbose == 1) printf(" ========================== Call NSGS solver SOCLCP problem ==========================\n"); internalsolver = &soclcp_nsgs; //internalsolver_options->internalSolvers->dWork = options->dWork; } else { fprintf(stderr, "Numerics, FrictionContact3D_SOCLCP failed. Unknown internal solver.\n"); exit(EXIT_FAILURE); } internalsolver_options->dparam[0]=options->dparam[0]; internalsolver_options->iparam[0]=options->iparam[0]; (*internalsolver)(soclcp, reaction , velocity , info , internalsolver_options); error = internalsolver_options->dparam[1]; double real_error=0.0; FrictionContact3D_compute_error(problem, reaction , velocity, tolerance, options, &real_error); if (options->callback) { options->callback->collectStatsIteration(options->callback->env, nc * 3, reaction, velocity, error, NULL); } if (verbose > 0) { printf("----------------------------------- FC3D - SOCLCP - # Iteration %i Final Error = %14.7e\n", internalsolver_options->iparam[7], error); printf("----------------------------------- FC3D - SOCLCP - # error of the real problem = %14.7e\n", real_error ); printf("----------------------------------- FC3D - SOCLCP - # gap with the real problem = %14.7e\n", fabs(real_error-error) ); } free(soclcp->q); free(soclcp->coneIndex); free(soclcp); if (internalsolver_options->internalSolvers != NULL) internalsolver_options->internalSolvers->dWork = NULL; dparam[0] = tolerance; dparam[1] = error; dparam[2] = fabs(real_error-error); iparam[7] = internalsolver_options->iparam[7]; }
int fc3d_driver(FrictionContactProblem* problem, double *reaction, double *velocity, SolverOptions* options, NumericsOptions* global_options) { if (options == NULL) numericsError("fc3d_driver", "null input for solver and/or global options"); int setnumericsoptions=0; /* Set global options */ if (global_options) { setNumericsOptions(global_options); options->numericsOptions = (NumericsOptions*) malloc(sizeof(NumericsOptions)); options->numericsOptions->verboseMode = global_options->verboseMode; setnumericsoptions=1; } int NoDefaultOptions = options->isSet; /* true(1) if the SolverOptions structure has been filled in else false(0) */ if (!NoDefaultOptions) readSolverOptions(3, options); if (verbose > 0) printSolverOptions(options); /* Solver name */ /*char * name = options->solverName;*/ int info = -1 ; if (problem->dimension != 3) numericsError("fc3d_driver", "Dimension of the problem : problem-> dimension is not compatible or is not set"); /* Check for trivial case */ info = checkTrivialCase(problem, velocity, reaction, options); if (info == 0) goto exit; switch (options->solverId) { /* Non Smooth Gauss Seidel (NSGS) */ case SICONOS_FRICTION_3D_NSGS: { snPrintf(1, options, " ========================== Call NSGS solver for Friction-Contact 3D problem ==========================\n"); fc3d_nsgs(problem, reaction , velocity , &info , options); break; } case SICONOS_FRICTION_3D_NSGSV: { snPrintf(1, options, " ========================== Call NSGSV solver for Friction-Contact 3D problem ==========================\n"); fc3d_nsgs_velocity(problem, reaction , velocity , &info , options); break; } /* Proximal point algorithm */ case SICONOS_FRICTION_3D_PROX: { snPrintf(1, options, " ========================== Call PROX (Proximal Point) solver for Friction-Contact 3D problem ==========================\n"); fc3d_proximal(problem, reaction , velocity , &info , options); break; } /* Tresca Fixed point algorithm */ case SICONOS_FRICTION_3D_TFP: { snPrintf(1, options, " ========================== Call TFP (Tresca Fixed Point) solver for Friction-Contact 3D problem ==========================\n"); fc3d_TrescaFixedPoint(problem, reaction , velocity , &info , options); break; } /* ACLM Fixed point algorithm */ case SICONOS_FRICTION_3D_ACLMFP: { snPrintf(1, options, " ========================== Call ACLM (Acary Cadoux Lemarechal Malick Fixed Point) solver for Friction-Contact 3D problem ==========================\n"); fc3d_ACLMFixedPoint(problem, reaction , velocity , &info , options); break; } /* SOCLCP Fixed point algorithm */ case SICONOS_FRICTION_3D_SOCLCP: { snPrintf(1, options, " ========================== Call SOCLCP solver for Friction-Contact 3D problem (Associated one) ==========================\n"); fc3d_SOCLCP(problem, reaction , velocity , &info , options); break; } /* De Saxce Fixed point algorithm */ case SICONOS_FRICTION_3D_DSFP: { snPrintf(1, options, " ========================== Call DeSaxce Fixed Point (DSFP) solver for Friction-Contact 3D problem ==========================\n"); fc3d_DeSaxceFixedPoint(problem, reaction , velocity , &info , options); break; } /* Fixed point projection algorithm */ case SICONOS_FRICTION_3D_FPP: { snPrintf(1, options, " ========================== Call Fixed Point Projection (FPP) solver for Friction-Contact 3D problem ==========================\n"); fc3d_fixedPointProjection(problem, reaction , velocity , &info , options); break; } /* Extra Gradient algorithm */ case SICONOS_FRICTION_3D_EG: { snPrintf(1, options, " ========================== Call ExtraGradient (EG) solver for Friction-Contact 3D problem ==========================\n"); fc3d_ExtraGradient(problem, reaction , velocity , &info , options); break; } /* VI Fixed Point Projection algorithm */ case SICONOS_FRICTION_3D_VI_FPP: { snPrintf(1, options, " ========================== Call VI_FixedPointProjection (VI_FPP) solver for Friction-Contact 3D problem ==========================\n"); fc3d_VI_FixedPointProjection(problem, reaction , velocity , &info , options); break; } /* VI Extra Gradient algorithm */ case SICONOS_FRICTION_3D_VI_EG: { snPrintf(1, options, " ========================== Call VI_ExtraGradient (VI_EG) solver for Friction-Contact 3D problem ==========================\n"); fc3d_VI_ExtraGradient(problem, reaction , velocity , &info , options); break; } /* Hyperplane Projection algorithm */ case SICONOS_FRICTION_3D_HP: { snPrintf(1, options, " ========================== Call Hyperplane Projection (HP) solver for Friction-Contact 3D problem ==========================\n"); fc3d_HyperplaneProjection(problem, reaction , velocity , &info , options); break; } /* Alart Curnier in local coordinates */ case SICONOS_FRICTION_3D_NSN_AC: { snPrintf(1, options, " ========================== Call Alart Curnier solver for Friction-Contact 3D problem ==========================\n"); if (problem->M->matrix0) { fc3d_nonsmooth_Newton_AlartCurnier(problem, reaction , velocity , &info , options); } else { fc3d_nonsmooth_Newton_AlartCurnier(problem, reaction , velocity , &info , options); } break; } /* Fischer Burmeister in local coordinates */ case SICONOS_FRICTION_3D_NSN_FB: { snPrintf(1, options, " ========================== Call Fischer Burmeister solver for Friction-Contact 3D problem ==========================\n"); fc3d_nonsmooth_Newton_FischerBurmeister(problem, reaction , velocity , &info , options); break; } case SICONOS_FRICTION_3D_NSN_NM: { snPrintf(1, options, " ========================== Call natural map solver for Friction-Contact 3D problem ==========================\n"); fc3d_nonsmooth_Newton_NaturalMap(problem, reaction , velocity , &info , options); break; } case SICONOS_FRICTION_3D_ONECONTACT_QUARTIC_NU: case SICONOS_FRICTION_3D_ONECONTACT_QUARTIC: { snPrintf(1, options, " ========================== Call Quartic solver for Friction-Contact 3D problem ==========================\n"); fc3d_unitary_enumerative(problem, reaction , velocity , &info , options); break; } case SICONOS_FRICTION_3D_ONECONTACT_NSN_AC: case SICONOS_FRICTION_3D_ONECONTACT_NSN_AC_GP: { snPrintf(1, options, " ========================== Call Newton-based solver for one contact Friction-Contact 3D problem ==========================\n"); fc3d_onecontact_nonsmooth_Newton_solvers_initialize(problem, problem, options); info = fc3d_onecontact_nonsmooth_Newton_solvers_solve(problem, reaction , options); break; } case SICONOS_FRICTION_3D_ONECONTACT_ProjectionOnConeWithLocalIteration: { snPrintf(1, options, " ========================== Call Projection on cone solver for one contact Friction-Contact 3D problem ==========================\n"); fc3d_projectionOnConeWithLocalIteration_initialize(problem, problem, options); info = fc3d_projectionOnConeWithLocalIteration_solve(problem, reaction , options); fc3d_projectionOnConeWithLocalIteration_free(problem, problem, options); break; } case SICONOS_FRICTION_3D_GAMS_PATH: { snPrintf(1, options, " ========================== Call PATH solver via GAMS for an AVI Friction-Contact 3D problem ==========================\n"); fc3d_AVI_gams_path(problem, reaction , velocity, &info, options); break; } case SICONOS_FRICTION_3D_GAMS_PATHVI: { snPrintf(1, options, " ========================== Call PATHVI solver via GAMS for an AVI Friction-Contact 3D problem ==========================\n"); fc3d_AVI_gams_pathvi(problem, reaction , velocity, &info, options); break; } case SICONOS_FRICTION_3D_GAMS_LCP_PATH: { snPrintf(1, options, " ========================== Call PATH solver via GAMS for an LCP-based reformulation of the AVI Friction-Contact 3D problem ==========================\n"); fc3d_lcp_gams_path(problem, reaction , velocity, &info, options); break; } case SICONOS_FRICTION_3D_GAMS_LCP_PATHVI: { snPrintf(1, options, " ========================== Call PATHVI solver via GAMS for an LCP-based reformulation of the AVI Friction-Contact 3D problem ==========================\n"); fc3d_lcp_gams_pathvi(problem, reaction , velocity, &info, options); break; } default: { fprintf(stderr, "Numerics, fc3d_driver failed. Unknown solver.\n"); exit(EXIT_FAILURE); } } exit: if (setnumericsoptions) { free(options->numericsOptions); options->numericsOptions = NULL; } return info; }
void fc3d_ACLMFixedPoint(FrictionContactProblem* problem, double *reaction, double *velocity, int* info, SolverOptions* options) { /* int and double parameters */ int* iparam = options->iparam; double* dparam = options->dparam; /* Number of contacts */ int nc = problem->numberOfContacts; /* Maximum number of iterations */ int itermax = iparam[0]; /* Tolerance */ double tolerance = dparam[0]; if (options->numberOfInternalSolvers < 1) { numericsError("fc3d_ACLMFixedpoint", "The ACLM Fixed Point method needs options for the internal solvers, options[0].numberOfInternalSolvers should be >1"); } SolverOptions * internalsolver_options = options->internalSolvers; if (verbose > 0) { printSolverOptions(options); } /***** Fixed Point Iterations *****/ int iter = 0; /* Current iteration number */ double error = 1.; /* Current error */ int hasNotConverged = 1; soclcp_InternalSolverPtr internalsolver; SecondOrderConeLinearComplementarityProblem* soclcp = (SecondOrderConeLinearComplementarityProblem *)malloc(sizeof(SecondOrderConeLinearComplementarityProblem)); soclcp->n = problem->numberOfContacts * problem->dimension; soclcp->nc= problem->numberOfContacts; soclcp->M = problem-> M; soclcp->q = (double *) malloc(soclcp->n * sizeof(double)); soclcp->mu = problem->mu; soclcp->coneIndex = (unsigned int *) malloc((soclcp->nc+1) * sizeof(unsigned int)); for (int i=0; i < soclcp->n; i++) { soclcp->q[i]=problem->q[i]; } for (int i=0; i < soclcp->nc+1; i++) { soclcp->coneIndex[i] = 3*i; } if (internalsolver_options->solverId == SICONOS_SOCLCP_NSGS) { if (verbose == 1) printf(" ========================== Call NSGS solver SOCLCP problem ==========================\n"); internalsolver = &soclcp_nsgs; //internalsolver_options->internalSolvers->dWork = options->dWork; } else { fprintf(stderr, "Numerics, fc3d_ACLMFixedPoint failed. Unknown internal solver.\n"); exit(EXIT_FAILURE); } double normUT; int cumul_iter =0; while ((iter < itermax) && (hasNotConverged > 0)) { ++iter; // internal solver for the regularized problem /* Compute the value of the initial value of q */ for (int ic = 0 ; ic < nc ; ic++) { normUT = sqrt(velocity[ic*3+1] * velocity[ic*3+1] + velocity[ic*3+2] * velocity[ic*3+2]); soclcp->q[3*ic] = problem->q[3*ic] + problem->mu[ic]*normUT; } //secondOrderConeLinearComplementarityProblem_printInFilename(soclcp,"output.dat"); // DEBUG_EXPR(for (int ic = 0 ; ic < nc ; ic++) printf("problem->q[%i] = %le\n", 3*ic, problem->q[3*ic]); // for (int ic = 0 ; ic < nc ; ic++) printf("q[%i] = %le\n", 3*ic, soclcp->q[3*ic]); ); if (iparam[1] == 0 ) { internalsolver_options->dparam[0] = max(error/10.0, options->dparam[0]/problem->numberOfContacts); } else if (iparam[1] ==1) { internalsolver_options->dparam[0] = options->dparam[0]/2.0; } else { fprintf(stderr, "Numerics, fc3d_ACLMFixedPoint failed. Unknown startegy for driving tolerence of internal.\n"); exit(EXIT_FAILURE); } (*internalsolver)(soclcp, reaction , velocity , info , internalsolver_options); cumul_iter += internalsolver_options->iparam[7]; /* **** Criterium convergence **** */ fc3d_compute_error(problem, reaction , velocity, tolerance, options, &error); if (options->callback) { options->callback->collectStatsIteration(options->callback->env, nc * 3, reaction, velocity, error, NULL); } if (verbose > 0) printf("------------------------ FC3D - ACLMFP - Iteration %i Residual = %14.7e\n", iter, error); if (error < tolerance) hasNotConverged = 0; *info = hasNotConverged; } if (verbose > 0) { printf("----------------------------------- FC3D - ACLMFP - # Iteration %i Final Residual = %14.7e\n", iter, error); printf("----------------------------------- FC3D - ACLMFP - # internal iteration = %i\n", cumul_iter); } free(soclcp->q); free(soclcp->coneIndex); free(soclcp); if (internalsolver_options->internalSolvers != NULL) internalsolver_options->internalSolvers->dWork = NULL; dparam[0] = tolerance; dparam[1] = error; iparam[7] = iter; }
int soclcp_driver(SecondOrderConeLinearComplementarityProblem* problem, double *r, double *v, SolverOptions* options, NumericsOptions* global_options) { if(options == NULL) numericsError("soclcp_driver", "null input for solver and/or global options"); int setnumericsoptions=0; /* Set global options */ if(global_options) { setNumericsOptions(global_options); options->numericsOptions = (NumericsOptions*) malloc(sizeof(NumericsOptions)); options->numericsOptions->verboseMode = global_options->verboseMode; setnumericsoptions=1; } int NoDefaultOptions = options->isSet; /* true(1) if the SolverOptions structure has been filled in else false(0) */ if(!NoDefaultOptions) readSolverOptions(3, options); if(verbose > 0) printSolverOptions(options); /* Solver name */ /*char * name = options->solverName;*/ int info = -1 ; /* Check for trivial case */ info = soclcp_checkTrivialCase(problem, v, r, options); if(info == 0) return info; switch(options->solverId) { /* Non Smooth Gauss Seidel (NSGS) */ case SICONOS_SOCLCP_NSGS: { snPrintf(1, options, " ========================== Call NSGS solver for Second Order Cone LCP problem ==========================\n"); soclcp_nsgs(problem, r , v , &info , options); break; } /* case SICONOS_SOCLCP_NSGSV: */ /* { */ /* snPrintf(1, options, */ /* " ========================== Call NSGSV solver for Second Order Cone LCP problem ==========================\n"); */ /* soclcp_nsgs_v(problem, r , v , &info , options); */ /* break; */ /* } */ /* /\* Proximal point algorithm *\/ */ /* case SICONOS_SOCLCP_PROX: */ /* { */ /* snPrintf(1, options, */ /* " ========================== Call PROX (Proximal Point) solver for Second Order Cone LCP problem ==========================\n"); */ /* soclcp_proximal(problem, r , v , &info , options); */ /* break; */ /* } */ /* /\* Tresca Fixed point algorithm *\/ */ /* case SICONOS_SOCLCP_TFP: */ /* { */ /* snPrintf(1, options, */ /* " ========================== Call TFP (Tresca Fixed Point) solver for Second Order Cone LCP problem ==========================\n"); */ /* soclcp_TrescaFixedPoint(problem, r , v , &info , options); */ /* break; */ /* } */ case SICONOS_SOCLCP_VI_FPP: { snPrintf(1, options, " ========================== Call VI_FixedPointProjection (VI_FPP) solver for Second Order Cone LCP problem ==========================\n"); soclcp_VI_FixedPointProjection(problem, r , v , &info , options); break; } /* VI Extra Gradient algorithm */ case SICONOS_SOCLCP_VI_EG: { snPrintf(1, options, " ========================== Call VI_ExtraGradient (VI_EG) solver for Second Order Cone LCP problem ==========================\n"); soclcp_VI_ExtraGradient(problem, r , v , &info , options); break; } /* /\* Hyperplane Projection algorithm *\/ */ /* case SICONOS_SOCLCP_HP: */ /* { */ /* snPrintf(1, options, */ /* " ========================== Call Hyperplane Projection (HP) solver for Second Order Cone LCP problem ==========================\n"); */ /* soclcp_HyperplaneProjection(problem, r , v , &info , options); */ /* break; */ /* } */ /* /\* Alart Curnier in local coordinates *\/ */ /* case SICONOS_SOCLCP_LOCALAC: */ /* { */ /* snPrintf(1, options, */ /* " ========================== Call Alart Curnier solver for Second Order Cone LCP problem ==========================\n"); */ /* if (problem->M->matrix0) */ /* { */ /* soclcp_localAlartCurnier(problem, r , v , &info , options); */ /* } */ /* else */ /* { */ /* soclcp_localAlartCurnier(problem, r , v , &info , options); */ /* } */ /* break; */ /* } */ /* /\* Fischer Burmeister in local coordinates *\/ */ /* case SICONOS_SOCLCP_LOCALFB: */ /* { */ /* snPrintf(1, options, */ /* " ========================== Call Fischer Burmeister solver for Second Order Cone LCP problem ==========================\n"); */ /* soclcp_localFischerBurmeister(problem, r , v , &info , options); */ /* break; */ /* } */ /* case SICONOS_SOCLCP_QUARTIC_NU: */ /* case SICONOS_SOCLCP_QUARTIC: */ /* { */ /* snPrintf(1, options, */ /* " ========================== Call Quartic solver for Second Order Cone LCP problem ==========================\n"); */ /* soclcp_unitary_enumerative(problem, r , v , &info , options); */ /* break; */ /* } */ /* case SICONOS_SOCLCP_AlartCurnierNewton: */ /* case SICONOS_SOCLCP_DampedAlartCurnierNewton: */ /* { */ /* snPrintf(1, options, */ /* " ========================== Call Quartic solver for Second Order Cone LCP problem ==========================\n"); */ /* info =soclcp_Newton_solve(problem, r , options); */ /* break; */ /* } */ default: { fprintf(stderr, "Numerics, SecondOrderConeLinearComplementarity_driver failed. Unknown solver.\n"); exit(EXIT_FAILURE); } } if(setnumericsoptions) { free(options->numericsOptions); options->numericsOptions = NULL; } return info; }
int fc2d_driver(FrictionContactProblem* problem, double *reaction , double *velocity, SolverOptions* options, NumericsOptions* global_options) { #ifdef DUMP_PROBLEM char fname[256]; sprintf(fname, "FrictionContactProblem%.5d.dat", fccounter++); printf("Dump of FrictionContactProblem%.5d.dat", fccounter); FILE * foutput = fopen(fname, "w"); frictionContact_printInFile(problem, foutput); fclose(foutput); #endif if (options == NULL || global_options == NULL) numericsError("fc2d_driver", "null input for solver and/or global options"); /* Set global options */ setNumericsOptions(global_options); /* Checks inputs */ if (problem == NULL || reaction == NULL || velocity == NULL) numericsError("fc2d_driver", "null input for FrictionContactProblem and/or unknowns (reaction,velocity)"); /* If the options for solver have not been set, read default values in .opt file */ int NoDefaultOptions = options->isSet; /* true(1) if the SolverOptions structure has been filled in else false(0) */ if (!NoDefaultOptions) readSolverOptions(3, options); if (verbose > 0) printSolverOptions(options); /* Solver name */ /*char * name = options->solverName;*/ int info = -1 ; if (problem->dimension != 2) numericsError("fc2d_driver", "Dimension of the problem : problem-> dimension is not compatible or is not set"); /* Non Smooth Gauss Seidel (NSGS) */ if (problem->M->storageType == 1) { if (options->solverId == SICONOS_FRICTION_2D_NSGS) { if (verbose) printf(" ======================= Call Sparse NSGS solver for Friction-Contact 2D problem ======================\n"); fc2d_sparse_nsgs(problem, reaction , velocity , &info , options); } else { fprintf(stderr, "fc2d_driver error: unknown solver named: %s\n", idToName(options->solverId)); exit(EXIT_FAILURE); } } else if (problem->M->storageType == 0) { switch (options->solverId) { /****** NLGS algorithm ******/ case SICONOS_FRICTION_2D_PGS: case SICONOS_FRICTION_2D_NSGS: { if (verbose) printf(" ========================== Call NLGS solver for Friction-Contact 2D problem ==========================\n"); fc2d_nsgs(problem, reaction, velocity, &info, options); break; } /****** CPG algorithm ******/ case SICONOS_FRICTION_2D_CPG: { if (verbose) printf(" ========================== Call CPG solver for Friction-Contact 2D problem ==========================\n"); fc2d_cpg(problem, reaction, velocity, &info, options); break; } /****** Latin algorithm ******/ case SICONOS_FRICTION_2D_LATIN: { if (verbose) printf(" ========================== Call Latin solver for Friction-Contact 2D problem ==========================\n"); fc2d_latin(problem, reaction, velocity, &info, options); break; } /****** Lexicolemke algorithm ******/ case SICONOS_FRICTION_2D_LEMKE: { if (verbose) printf(" ========================== Call Lemke solver for Friction-Contact 2D problem ==========================\n"); fc2d_lexicolemke(problem, reaction, velocity, &info, options, global_options); break; } /****** Enum algorithm ******/ case SICONOS_FRICTION_2D_ENUM: { if (verbose) printf(" ========================== Call Enumerative solver for Friction-Contact 2D problem ==========================\n"); fc2d_enum(problem, reaction, velocity, &info, options, global_options); break; } /*error */ default: { fprintf(stderr, "fc2d_driver error: unknown solver named: %s\n", idToName(options->solverId)); exit(EXIT_FAILURE); } } #ifdef DUMP_PROBLEM_IF_INFO if (info) { char fname[256]; sprintf(fname, "FrictionContactProblem%.5d.dat", fccounter++); printf("Dump of FrictionContactProblem%.5d.dat\n", fccounter); FILE * foutput = fopen(fname, "w"); frictionContact_printInFile(problem, foutput); fclose(foutput); } #endif } else { numericsError("fc2d_driver", " error: unknown storagetype named"); exit(EXIT_FAILURE); } return info; }