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 <float.h>                          // for DBL_EPSILON
20 #include <stdio.h>                          // for fprintf, NULL, stderr
21 #include <string.h>                         // for strcat, strcpy
22 #include "Friction_cst.h"                   // for SICONOS_ROLLING_FRICTION_...
23 #include "NonSmoothDrivers.h"               // for rolling_fc2d_driver
24 #include "NumericsFwd.h"                    // for SolverOptions, RollingFri...
25 #include "RollingFrictionContactProblem.h"  // for RollingFrictionContactPro...
26 #include "SolverOptions.h"                  // for SolverOptions, solver_opt...
27 #include "numerics_verbose.h"               // for numerics_error, numerics_...
28 #include "rolling_fc_Solvers.h"           // for rolling_fc2d_nsgs, rollin...
29 
30 const char* const   SICONOS_ROLLING_FRICTION_2D_NSGS_STR = "RFC2D_NSGS";
31 
32 const char* const  SICONOS_ROLLING_FRICTION_2D_ONECONTACT_ProjectionOnConeWithLocalIteration_STR = "RFC2D_ProjectionOnConeWithLocalIteration";
33 
34 
35 const char* const  SICONOS_ROLLING_FRICTION_2D_ONECONTACT_ProjectionOnCone_STR = "RFC2D_ProjectionOnCone";
36 
rolling_fc2d_driver(RollingFrictionContactProblem * problem,double * reaction,double * velocity,SolverOptions * options)37 int rolling_fc2d_driver(RollingFrictionContactProblem* problem,
38                         double *reaction, double *velocity,
39                         SolverOptions* options)
40 {
41   /* verbose=3; */
42   /* rollingFrictionContact_display(problem); */
43   /* rollingFrictionContact_printInFilename(problem, "rfc3d_sphere_1.dat"); */
44 
45 
46 
47   if(options == NULL)
48     numerics_error("rolling_fc2d_driver", "null input for solver options");
49 
50   assert(options->isSet); /* true(1) if the SolverOptions structure has been filled in else false(0) */
51 
52   if(verbose > 1)
53     solver_options_print(options);
54 
55   int info = -1 ;
56 
57   if(problem->dimension != 3)
58   {
59     numerics_warning("rolling_fc2d_driver", "Dimension of the problem : problem-> dimension is not compatible or is not set");
60     numerics_error("rolling_fc2d_driver", "Dimension of the problem : problem-> dimension is not compatible or is not set");
61   }
62   /* Check for trivial case */
63   info = rolling_fc2d_checkTrivialCase(problem, velocity, reaction, options);
64   if(info == 0)
65   {
66     /* If a trivial solution is found, we set the number of iterations to 0
67        and the reached acuracy to 0.0 .
68     */
69     options->iparam[SICONOS_IPARAM_ITER_DONE] = 0;
70     options->dparam[SICONOS_DPARAM_RESIDU] = 0.0;
71     goto exit;
72   }
73 
74 
75   switch(options->solverId)
76   {
77   /* Non Smooth Gauss Seidel (NSGS) */
78   case SICONOS_ROLLING_FRICTION_2D_NSGS:
79   {
80     numerics_printf(" ========================== Call NSGS solver for Rolling Friction-Contact 2D problem ==========================\n");
81     rolling_fc2d_nsgs(problem, reaction, velocity, &info, options);
82     break;
83   }
84   default:
85   {
86     char  msg[200];
87     strcpy(msg, "Unknown solver : ");
88     strcat(msg, solver_options_id_to_name(options->solverId));
89     strcat(msg, "\n");
90     numerics_warning("rolling_fc2d_driver",  msg);
91     numerics_error("rolling_fc2d_driver",  msg);
92   }
93   }
94 
95 exit:
96 
97   return info;
98 
99 }
100 
101 
rolling_fc2d_checkTrivialCase(RollingFrictionContactProblem * problem,double * velocity,double * reaction,SolverOptions * options)102 int rolling_fc2d_checkTrivialCase(RollingFrictionContactProblem* problem, double* velocity,
103                                   double* reaction, SolverOptions* options)
104 {
105   /* Number of contacts */
106   int nc = problem->numberOfContacts;
107   double* q = problem->q;
108   /* Dimension of the problem */
109   int n = 3 * nc;
110   int i = 0;
111   /*take off? R=0 ?*/
112   for(i = 0; i < nc; i++)
113   {
114     if(q[3 * i] < -DBL_EPSILON)
115       return -1;
116   }
117   for(i = 0 ; i < n ; ++i)
118   {
119     velocity[i] = q[i];
120     reaction[i] = 0.;
121   }
122 
123   numerics_printf("rolling_fc2d rolling_fc2d_checkTrivialCase, take off, trivial solution reaction = 0, velocity = q.\n");
124   return 0;
125 }
126