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