1 /* Siconos is a program dedicated to modeling, simulation and control
2 * of non smooth dynamical systems.
3 *
4 * Copyright 2021 INRIA.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 #include <assert.h> // for assert
19 #include <stdio.h> // for printf, NULL, fprintf, stderr
20 #include <stdlib.h> // for exit, malloc, EXIT_FAILURE
21 #include "FrictionContactProblem.h" // for FrictionContactProblem
22 #include "Friction_cst.h" // for SICONOS_FRICTION_2D_NSGS, SICONO...
23 #include "NonSmoothDrivers.h" // for fc2d_driver
24 #include "NumericsFwd.h" // for FrictionContactProblem, SolverOp...
25 #include "NumericsMatrix.h" // for NumericsMatrix, RawNumericsMatrix
26 #include "SolverOptions.h" // for SolverOptions, solver_options_id...
27 #include "SparseBlockMatrix.h" // for SparseBlockStructuredMatrix, SBM...
28 #include "fc2d_Solvers.h" // for fc2d_cpg, fc2d_enum
29 #include "numerics_verbose.h" // for numerics_error, verbose, numeric...
30
31 const char* const SICONOS_FRICTION_2D_NSGS_STR = "F2D_NSGS";
32 const char* const SICONOS_FRICTION_2D_CPG_STR = "F2D_CPG";
33 const char* const SICONOS_FRICTION_2D_LEMKE_STR = "F2D_LEMKE";
34 const char* const SICONOS_FRICTION_2D_ENUM_STR = "F2D_ENUM";
35 //#define DUMP_PROBLEM
36 #ifdef DUMP_PROBLEM
37 static int fccounter = 0;
38 #endif
39 //#define DUMP_PROBLEM_IF_INFO
40 #ifdef DUMP_PROBLEM_IF_INFO
41 static int fccounter = 0;
42 #endif
43
44
fc2d_driver(FrictionContactProblem * problem,double * reaction,double * velocity,SolverOptions * options)45 int fc2d_driver(FrictionContactProblem* problem, double *reaction, double *velocity, SolverOptions* options)
46 {
47
48 #ifdef DUMP_PROBLEM
49 char fname[256];
50 sprintf(fname, "FrictionContactProblem%.5d.dat", fccounter++);
51 printf("Dump of FrictionContactProblem%.5d.dat", fccounter);
52
53 FILE * foutput = fopen(fname, "w");
54 frictionContact_printInFile(problem, foutput);
55 fclose(foutput);
56 #endif
57
58 if(options == NULL)
59 numerics_error("fc2d_driver", "null input for solver options");
60
61 /* Checks inputs */
62 if(problem == NULL || reaction == NULL || velocity == NULL)
63 numerics_error("fc2d_driver", "null input for FrictionContactProblem and/or unknowns (reaction,velocity)");
64
65 assert(options->isSet);
66
67 if(verbose > 0)
68 solver_options_print(options);
69
70
71 /* Solver name */
72 /*const char* const name = options->solverName;*/
73
74
75 int info = -1 ;
76
77 if(problem->dimension != 2)
78 numerics_error("fc2d_driver", "Dimension of the problem : problem-> dimension is not compatible or is not set");
79
80
81 /* Non Smooth Gauss Seidel (NSGS) */
82
83 if(problem->M->storageType == 1)
84 {
85
86 if(options->solverId == SICONOS_FRICTION_2D_NSGS)
87 {
88 numerics_printf(" ======================= Call Sparse NSGS solver for Friction-Contact 2D problem ======================");
89 fc2d_nsgs_sbm(problem, reaction, velocity, &info, options);
90 }
91 else
92 {
93
94 SparseBlockStructuredMatrix * M = problem->M->matrix1;
95 int n = M->blocksize0[M->blocknumber0 - 1];
96 int m = M->blocksize1[M->blocknumber1 - 1];
97 double * denseMat = (double*)malloc(n*m*sizeof(double));
98 SBM_to_dense(M, denseMat);
99
100 problem->M->matrix0 = denseMat;
101 problem->M->storageType =0;
102 info = fc2d_driver(problem, reaction, velocity, options);
103
104 NM_clearDense(problem->M);
105 problem->M->matrix1 = M;
106 problem->M->storageType =1;
107
108
109 }
110
111 }
112 else if(problem->M->storageType == 0)
113 {
114
115 switch(options->solverId)
116 {
117 /****** NLGS algorithm ******/
118 case SICONOS_FRICTION_2D_NSGS:
119 {
120 if(verbose)
121 printf(" ========================== Call NLGS solver for Friction-Contact 2D problem ==========================\n");
122 fc2d_nsgs_dense(problem, reaction, velocity, &info, options);
123 break;
124 }
125 /****** CPG algorithm ******/
126 case SICONOS_FRICTION_2D_CPG:
127 {
128 if(verbose)
129 printf(" ========================== Call CPG solver for Friction-Contact 2D problem ==========================\n");
130 fc2d_cpg(problem, reaction, velocity, &info, options);
131 break;
132 }
133 /****** Lexicolemke algorithm ******/
134 case SICONOS_FRICTION_2D_LEMKE:
135 {
136 if(verbose)
137 printf(" ========================== Call Lemke solver for Friction-Contact 2D problem ==========================\n");
138 fc2d_lexicolemke(problem, reaction, velocity, &info, options);
139 break;
140 }
141 /****** Enum algorithm ******/
142 case SICONOS_FRICTION_2D_ENUM:
143 {
144 if(verbose)
145 printf(" ========================== Call Enumerative solver for Friction-Contact 2D problem ==========================\n");
146 fc2d_enum(problem, reaction, velocity, &info, options);
147 break;
148 }
149 /*error */
150 default:
151 {
152 fprintf(stderr, "fc2d_driver error: unknown solver named: %s\n", solver_options_id_to_name(options->solverId));
153 exit(EXIT_FAILURE);
154 }
155 }
156 #ifdef DUMP_PROBLEM_IF_INFO
157 if(info)
158 {
159 char fname[256];
160 sprintf(fname, "FrictionContactProblem%.5d.dat", fccounter++);
161 printf("Dump of FrictionContactProblem%.5d.dat\n", fccounter);
162
163 FILE * foutput = fopen(fname, "w");
164 frictionContact_printInFile(problem, foutput);
165 fclose(foutput);
166 }
167 #endif
168 }
169 else
170 {
171 numerics_error("fc2d_driver",
172 " error: unknown storagetype named");
173 exit(EXIT_FAILURE);
174 }
175
176 return info;
177
178 }
179