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