fctst_merit.c
Go to the documentation of this file.
1 /* FCLIB Copyright (C) 2011--2016 FClib project
2  *
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * Contact: fclib-project@lists.gforge.inria.fr
17 */
18 
19 
20 /*
21  * fctst.c
22  * ----------------------------------------------
23  * frictional contact test
24  */
25 
26 #include <string.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <time.h>
30 #include "fclib.h"
31 
32 /* useful macros */
33 #define ASSERT(Test, ...)\
34  do {\
35  if (! (Test)) { fprintf (stderr, "%s: %d => ", __FILE__, __LINE__);\
36  fprintf (stderr, __VA_ARGS__);\
37  fprintf (stderr, "\n"); exit (1); } } while (0)
38 
39 #define IO(Call) ASSERT ((Call) >= 0, "ERROR: HDF5 call failed")
40 #define MM(Call) ASSERT ((Call), "ERROR: out of memory")
41 
42 /* allocate matrix info */
43 static struct fclib_matrix_info* matrix_info (struct fclib_matrix *mat, char *comment)
44 {
45  struct fclib_matrix_info *info;
46 
47  MM (info = malloc (sizeof (struct fclib_matrix_info)));
48  MM (info->comment = malloc (strlen (comment) + 1));
49  strcpy (info->comment, comment);
50  info->conditioning = rand ();
51  info->determinant = rand ();
52  info->rank = mat->m;
53 
54  return info;
55 }
56 
57 /* generate random sparse matrix */
58 static struct fclib_matrix* random_matrix (int m, int n)
59 {
60  struct fclib_matrix *mat;
61  int j;
62 
63  MM (mat = malloc (sizeof (struct fclib_matrix)));
64  mat->m = m;
65  mat->n = n;
66  mat->nzmax = (m + n) + m*n / (10 + rand () % 10);
67  if (mat->nzmax > m*n) mat->nzmax = m*n;
68 
69  if (rand () % 2) /* triplet */
70  {
71  mat->nz = mat->nzmax;
72  MM (mat->p = malloc (sizeof(int)*mat->nzmax));
73  MM (mat->i = malloc (sizeof(int)*mat->nzmax));
74  for (j = 0; j < mat->nzmax; j ++)
75  {
76  mat->p [j] = rand () % mat->m;
77  mat->i [j] = rand () % mat->n;
78  }
79  }
80  else
81  {
82  mat->nz = (rand () % 2 ? -1 : -2); /* csc / csr */
83  int k = (mat->nz == -1 ? mat->n : mat->m);
84  MM (mat->p = malloc (sizeof(int)*(k+1)));
85  MM (mat->i = malloc (sizeof(int)*mat->nzmax));
86  int l = mat->nzmax / k;
87  for (mat->p [0] = j = 0; j < k; j ++) mat->p [j+1] = mat->p [j] + l;
88  for (j = 0; j < mat->nzmax; j ++) mat->i [j] = rand () % k;
89  }
90 
91  MM (mat->x = malloc (sizeof(double)*mat->nzmax));
92  for (j = 0; j < mat->nzmax; j ++) mat->x [j] = (double) rand () / (double) RAND_MAX;
93 
94  if (rand ()) mat->info = matrix_info (mat, "A random matrix");
95  else mat->info = NULL;
96 
97  return mat;
98 }
99 
100 /* generate random vector */
101 static double* random_vector (int n)
102 {
103  double *v;
104 
105  MM (v = malloc (sizeof(double)*n));
106  for (n --; n >= 0; n --) v [n] = (double) rand () / (double) RAND_MAX;
107 
108  return v;
109 }
110 
111 /* allocate problem info */
112 static struct fclib_info* problem_info (char *title, char *desc, char *math)
113 {
114  struct fclib_info *info;
115 
116  MM (info = malloc (sizeof (struct fclib_info)));
117  MM (info->title = malloc (strlen (title) + 1));
118  strcpy (info->title, title);
119  MM (info->description = malloc (strlen (desc) + 1));
120  strcpy (info->description, desc);
121  MM (info->math_info = malloc (strlen (math) + 1));
122  strcpy (info->math_info, math);
123 
124  return info;
125 }
126 
127 /* generate random global problem */
128 static struct fclib_global* random_global_problem (int global_dofs, int contact_points, int neq)
129 {
130  struct fclib_global *problem;
131 
132  MM (problem = malloc (sizeof (struct fclib_global)));
133  if (rand () % 2) problem->spacedim = 2;
134  else problem->spacedim = 3;
135  problem->M = random_matrix (global_dofs, global_dofs);
136  problem->H = random_matrix (global_dofs, problem->spacedim*contact_points);
137  if (neq && rand () % 2) problem->G = random_matrix (global_dofs, neq);
138  else problem->G = NULL;
139  problem->mu = random_vector (contact_points);
140  problem->f = random_vector (global_dofs);
141  if (problem->G) problem->b = random_vector (problem->G->n);
142  else problem->b = NULL;
143  problem->w = random_vector (problem->spacedim*contact_points);
144  if (rand () % 2) problem->info = problem_info ("A random global problem", "With random matrices", "And fake math");
145  else problem->info = NULL;
146 
147  return problem;
148 }
149 
150 /* generate random global solutions */
151 static struct fclib_solution* random_global_solutions (struct fclib_global *problem, int count)
152 {
153  struct fclib_solution *sol;
154  int i;
155 
156  MM (sol = malloc (count * sizeof (struct fclib_solution)));
157 
158  for (i = 0; i < count; i ++)
159  {
160  sol [i].v = random_vector (problem->M->n);
161  sol [i].u = random_vector (problem->H->n);
162  sol [i].r = random_vector (problem->H->n);
163  if (problem->G) sol [i].l = random_vector (problem->G->n);
164  else sol [i].l = NULL;
165  }
166 
167  return sol;
168 }
169 
170 /* generate random local problem */
171 static struct fclib_local* random_local_problem (int contact_points, int neq)
172 {
173  struct fclib_local *problem;
174 
175  MM (problem = malloc (sizeof (struct fclib_local)));
176  if (rand () % 2) problem->spacedim = 2;
177  else problem->spacedim = 3;
178  problem->W = random_matrix (problem->spacedim*contact_points, problem->spacedim*contact_points);
179  if (neq && rand () % 2)
180  {
181  problem->V = random_matrix (problem->spacedim*contact_points, neq);
182  problem->R = random_matrix (neq, neq);
183  problem->s = random_vector (neq);
184  }
185  else
186  {
187  problem->V = problem->R = NULL;
188  problem->s = NULL;
189  }
190  problem->mu = random_vector (contact_points);
191  problem->q = random_vector (problem->spacedim*contact_points);
192  if (rand () % 2) problem->info = problem_info ("A random local problem", "With random matrices", "And fake math");
193  else problem->info = NULL;
194 
195  return problem;
196 }
197 
198 /* generate random local solutions */
199 static struct fclib_solution* random_local_solutions (struct fclib_local *problem, int count)
200 {
201  struct fclib_solution *sol;
202  int i;
203 
204  MM (sol = malloc (count * sizeof (struct fclib_solution)));
205 
206  for (i = 0; i < count; i ++)
207  {
208  sol [i].v = NULL;
209  sol [i].u = random_vector (problem->W->n);
210  sol [i].r = random_vector (problem->W->n);
211  if (problem->R) sol [i].l = random_vector (problem->R->n);
212  else sol [i].l = NULL;
213  }
214 
215  return sol;
216 }
217 
218 /* compare matrix infos */
220 {
221  if (!a && !b) return 1;
222  else if ((a && !b) || (!a && b)) return 0;
223  else if (strcmp (a->comment, b->comment) != 0 ||
224  a->conditioning != b->conditioning ||
225  a->determinant != b->determinant ||
226  a->rank != b->rank) return 0;
227 
228  return 1;
229 }
230 
231 /* compare two matrices */
232 static int compare_matrices (char *name, struct fclib_matrix *a, struct fclib_matrix *b)
233 {
234  int i;
235 
236  if (!a && !b) return 1;
237  else if ((a && !b) || (!a && b)) return 0;
238 
239  if (a->nzmax != b->nzmax ||
240  a->n != b->n ||
241  a->m != b->m ||
242  a->nz != b->nz)
243  {
244  fprintf (stderr,
245  "ERROR: dimensions of matrix %s differ:\n"
246  "a->nzmax = %d, b->nzmax = %d\n"
247  "a->n = %d, b->n = %d\n"
248  "a->m = %d, b->m = %d\n"
249  "a->nz = %d, b->nz = %d\n", name,
250  a->nzmax, b->nzmax,
251  a->n, b->n,
252  a->m, b->m,
253  a->nz, b->nz);
254  return 0;
255  }
256 
257  if (a->nz >= 0)
258  {
259  for (i = 0; i < a->nzmax; i ++)
260  {
261  if (a->p [i] != b->p [i])
262  {
263  fprintf (stderr,
264  "ERROR: For %s in {a,b} a->p [%d] != b->p [%d] => %d != %d\n",
265  name, i, i, a->p [i], b->p [i]);
266  return 0;
267  }
268  if (a->i [i] != b->i [i])
269  {
270  fprintf (stderr,
271  "ERROR: For %s in {a,b} a->i [%d] != b->i [%d] => %d != %d\n",
272  name, i, i, a->i [i], b->i [i]);
273  return 0;
274  }
275  }
276  }
277  else if (a->nz == -1)
278  {
279  for (i = 0; i < a->n+1; i ++)
280  if (a->p [i] != b->p [i])
281  {
282  fprintf (stderr,
283  "ERROR: For %s in {a,b} a->p [%d] != b->p [%d] => %d != %d\n",
284  name, i, i, a->p [i], b->p [i]);
285  return 0;
286  }
287 
288  for (i = 0; i < a->nzmax; i ++)
289  if (a->i [i] != b->i [i])
290  {
291  fprintf (stderr,
292  "ERROR: For %s in {a,b} a->i [%d] != b->i [%d] => %d != %d\n",
293  name, i, i, a->i [i], b->i [i]);
294  return 0;
295  }
296  }
297  else if (a->nz == -2)
298  {
299  for (i = 0; i < a->m+1; i ++)
300  if (a->p [i] != b->p [i])
301  {
302  fprintf (stderr,
303  "ERROR: For %s in {a,b} a->p [%d] != b->p [%d] => %d != %d\n",
304  name, i, i, a->p [i], b->p [i]);
305  return 0;
306  }
307 
308  for (i = 0; i < a->nzmax; i ++)
309  if (a->i [i] != b->i [i])
310  {
311  fprintf (stderr,
312  "ERROR: For %s in {a,b} a->i [%d] != b->i [%d] => %d != %d\n",
313  name, i, i, a->i [i], b->i [i]);
314  return 0;
315  }
316  }
317 
318  for (i = 0; i < a->nzmax; i ++)
319  if (a->x [i] != b->x [i])
320  {
321  fprintf (stderr,
322  "ERROR: For %s in {a, b} a->x [%d] != b->x [%d] => %g != %g\n",
323  name, i, i, a->x [i], b->x [i]);
324  return 0;
325  }
326 
327  if (! compare_matrix_infos (a->info, b->info))
328  {
329  fprintf (stderr, "ERROR: matrix %s infos differ\n", name);
330  return 0;
331  }
332 
333  return 1;
334 }
335 
336 /* compare two vectors */
337 static int compare_vectors (char *name, int n, double *a, double *b)
338 {
339  int i;
340 
341  if (!a && !b) return 1;
342  else if ((a && !b) || (!a && b)) return 0;
343 
344  for (i = 0; i < n; i ++)
345  if (a [i] != b [i])
346  {
347  fprintf (stderr,
348  "ERROR: for %s in {a, b} a [%d] != b [%d] => %g != %g\n",
349  name, i, i, a [i], b [i]);
350  return 0;
351  }
352 
353  return 1;
354 }
355 
356 /* compare problem infos */
357 static int compare_infos (struct fclib_info *a, struct fclib_info *b)
358 {
359  if (!a && !b) return 1;
360  else if ((a && !b) || (!a && b)) return 0;
361  else if (strcmp (a->title, b->title) != 0 ||
362  strcmp (a->description, b->description) != 0 ||
363  strcmp (a->math_info, b->math_info) != 0) return 0;
364 
365  return 1;
366 }
367 
368 /* compare global problems */
369 static int compare_global_problems (struct fclib_global *a, struct fclib_global *b)
370 {
371  if (! compare_matrices ("M", a->M, b->M) ||
372  ! compare_matrices ("H", a->H, b->H) ||
373  ! compare_matrices ("G", a->G, b->G) ||
374  ! compare_vectors ("mu", a->H->n / a->spacedim, a->mu, b->mu) ||
375  ! compare_vectors ("f", a->M->m, a->f, b->f) ||
376  ! compare_vectors ("b", a->G ? a->G->n : 0, a->b, b->b) ||
377  ! compare_vectors ("w", a->H->n, a->w, b->w) ||
378  a->spacedim != b->spacedim ||
379  ! compare_infos (a->info, b->info)) return 0;
380 
381  return 1;
382 }
383 
384 /* compare local problems */
385 static int compare_local_problems (struct fclib_local *a, struct fclib_local *b)
386 {
387  if (! compare_matrices ("W", a->W, b->W) ||
388  ! compare_matrices ("V", a->V, b->V) ||
389  ! compare_matrices ("R", a->R, b->R) ||
390  ! compare_vectors ("mu", a->W->n / a->spacedim, a->mu, b->mu) ||
391  ! compare_vectors ("q", a->W->n, a->q, b->q) ||
392  ! compare_vectors ("s", a->R ? a->R->n : 0, a->s, b->s) ||
393  a->spacedim != b->spacedim ||
394  ! compare_infos (a->info, b->info)) return 0;
395 
396  return 1;
397 }
398 
399 /* compare solutions */
400 static int compare_solutions (struct fclib_solution *a, struct fclib_solution *b, int nv, int nr, int nl)
401 {
402  if (! compare_vectors ("v", nv, a->v, b->v) ||
403  ! compare_vectors ("u", nr, a->u, b->u) ||
404  ! compare_vectors ("r", nr, a->r, b->r) ||
405  ! compare_vectors ("l", nl, a->l, b->l)) return 0;
406 
407  return 1;
408 }
409 
410 int main (int argc, char **argv)
411 {
412  int i;
413  if (0)
414  {
415  struct fclib_global *problem, *p;
416  struct fclib_solution *solution, *s;
417  struct fclib_solution *guesses, *g;
418  int numguess;
419 
420  problem = fclib_read_global ("output_file.hdf5");
421  solution = fclib_read_solution ("output_file.hdf5");
422  guesses = fclib_read_guesses ("output_file.hdf5", &numguess);
423 
424  printf ("Computing merit function ...\n");
425  double error1 = fclib_merit_global (problem, MERIT_1, solution);
426  printf ("Error for initial problem = %12.8e\n", error1);
427 
428  fclib_delete_global (problem);
429  free(problem);
430  fclib_delete_solutions (solution, 1);
431  fclib_delete_solutions (guesses, numguess);
432  }
433  else
434  {
435 
436  struct fclib_local *problem, *p;
437  struct fclib_solution *solution, *s;
438  struct fclib_solution *guesses, *g;
439  short allfine = 0;
440  int numguess=1;
441  problem = fclib_read_local ("local_problem_test.hdf5");
442  solution = fclib_read_solution ("local_problem_test.hdf5");
443  guesses = fclib_read_guesses ("local_problem_test.hdf5", &numguess);
444 
445 
446  printf ("Computing merit function ...\n");
447 
448  double error1 = fclib_merit_local (problem, MERIT_1, solution);
449  printf ("Error for local problem = %12.8e\n", error1);
450 
451 
452  fclib_delete_local (problem);
453  free(problem);
454  fclib_delete_solutions (solution, 1);
455  fclib_delete_solutions (guesses, numguess);
456  }
457 
458  return 0;
459 }
char * description
short decription of the problem
Definition: fclib.h:115
double determinant
determinant
Definition: fclib.h:132
double * l
multiplier for equlity constraints ( ) solution vector
Definition: fclib.h:284
struct fclib_matrix * M
the matrix M (see mathematical description below)
Definition: fclib.h:198
double * r
local contact forces (or impulses) solution vector
Definition: fclib.h:282
static int compare_global_problems(struct fclib_global *a, struct fclib_global *b)
Definition: fctst_merit.c:369
struct fclib_matrix * G
the matrix M (see mathematical description below)
Definition: fclib.h:202
char * math_info
known properties of the problem (existence, uniqueness, ...)
Definition: fclib.h:117
double * w
the vector w (see mathematical description below)
Definition: fclib.h:210
char * title
title of the problem
Definition: fclib.h:113
int n
number of columns
Definition: fclib.h:147
matrix in compressed row/column or triplet form
Definition: fclib.h:140
FCLIB_STATIC struct fclib_global * fclib_read_global(const char *path)
read global problem; return problem on success; NULL on failure
Definition: fclib.h:1011
FCLIB_STATIC void fclib_delete_solutions(struct fclib_solution *data, int count)
delete solutions or guesses
Definition: fclib.h:1210
A solution or a guess for the frictional contact problem.
Definition: fclib.h:275
struct fclib_matrix * V
the matrix V (see mathematical description below)
Definition: fclib.h:254
static int compare_local_problems(struct fclib_local *a, struct fclib_local *b)
Definition: fctst_merit.c:385
MERIT_1
Definition: fclib.h:290
double * mu
the vector of coefficient of friction (see mathematical description below)
Definition: fclib.h:204
int nzmax
maximum number of entries
Definition: fclib.h:143
static int compare_infos(struct fclib_info *a, struct fclib_info *b)
Definition: fctst_merit.c:357
static int compare_matrix_infos(struct fclib_matrix_info *a, struct fclib_matrix_info *b)
Definition: fctst_merit.c:219
static struct fclib_matrix * random_matrix(int m, int n)
Definition: fctst_merit.c:58
FCLIB_STATIC struct fclib_solution * fclib_read_solution(const char *path)
read solution; return solution on success; NULL on failure
Definition: fclib.h:1117
struct fclib_matrix * R
the matrix R (see mathematical description below)
Definition: fclib.h:256
FCLIB_STATIC struct fclib_solution * fclib_read_guesses(const char *path, int *number_of_guesses)
read initial guesses; return vector of guesses on success; NULL on failure; output number of guesses ...
Definition: fclib.h:1145
int * p
compressed: row (size m+1) or column (size n+1) pointers; triplet: row indices (size nz) ...
Definition: fclib.h:149
int * i
compressed: column or row indices, size nzmax; triplet: column indices (size nz)
Definition: fclib.h:151
double * q
the vector q (see mathematical description below)
Definition: fclib.h:260
static struct fclib_solution * random_local_solutions(struct fclib_local *problem, int count)
Definition: fctst_merit.c:199
int spacedim
the dimension , 2 or 3, of the local space at contact (2d or 3d friction contact laws) ...
Definition: fclib.h:264
int nz
of entries in triplet matrix, -1 for compressed columns, -2 for compressed rows
Definition: fclib.h:155
int main(int argc, char **argv)
Definition: fctst_merit.c:410
double * f
the vector f (see mathematical description below)
Definition: fclib.h:206
double * b
the vector b (see mathematical description below)
Definition: fclib.h:208
static struct fclib_info * problem_info(char *title, char *desc, char *math)
Definition: fctst_merit.c:112
static int compare_matrices(char *name, struct fclib_matrix *a, struct fclib_matrix *b)
Definition: fctst_merit.c:232
static int compare_vectors(char *name, int n, double *a, double *b)
Definition: fctst_merit.c:337
static double * random_vector(int n)
Definition: fctst_merit.c:101
FCLIB_STATIC void fclib_delete_local(struct fclib_local *problem)
delete local problem
Definition: fclib.h:1198
int rank
rank
Definition: fclib.h:134
This structure allows the user to enter a description for a given matrix (comment, conditionning, determinant, rank.) if they are known.
Definition: fclib.h:125
double conditioning
conditioning
Definition: fclib.h:130
struct fclib_matrix * W
the matrix W (see mathematical description below)
Definition: fclib.h:252
double * x
numerical values, size nzmax
Definition: fclib.h:153
double * u
local velocity (or position/displacement for quasi-static problems) solution vector ...
Definition: fclib.h:280
static struct fclib_solution * random_global_solutions(struct fclib_global *problem, int count)
Definition: fctst_merit.c:151
struct fclib_matrix * H
the matrix M (see mathematical description below)
Definition: fclib.h:200
FCLIB_STATIC void fclib_delete_global(struct fclib_global *problem)
delete global problem
Definition: fclib.h:1185
FCLIB_STATIC struct fclib_local * fclib_read_local(const char *path)
read local problem; return problem on success; NULL on failure
Definition: fclib.h:1061
#define MM(Call)
Definition: fctst_merit.c:40
struct fclib_info * info
info on the problem
Definition: fclib.h:214
static struct fclib_matrix_info * matrix_info(struct fclib_matrix *mat, char *comment)
Definition: fctst_merit.c:43
static struct fclib_global * random_global_problem(int global_dofs, int contact_points, int neq)
Definition: fctst_merit.c:128
double * v
global velocity (or position/displacement for quasi-static problems) solution vector ...
Definition: fclib.h:278
static struct fclib_local * random_local_problem(int contact_points, int neq)
Definition: fctst_merit.c:171
char * comment
comment on the matrix properties
Definition: fclib.h:128
double * mu
the vector of coefficient of friction (see mathematical description below)
Definition: fclib.h:258
static int compare_solutions(struct fclib_solution *a, struct fclib_solution *b, int nv, int nr, int nl)
Definition: fctst_merit.c:400
int spacedim
the dimension , 2 or 3, of the local space at contact (2d or 3d friction contact laws) ...
Definition: fclib.h:212
The global frictional contact problem defined by.
Definition: fclib.h:195
double * s
the vector s (see mathematical description below)
Definition: fclib.h:262
struct fclib_info * info
info on the problem
Definition: fclib.h:266
The local frictional contact problem defined by.
Definition: fclib.h:249
This structure allows the user to enter a problem information as a title, a short description and kno...
Definition: fclib.h:110
struct fclib_matrix_info * info
info for this matrix
Definition: fclib.h:157
int m
number of rows
Definition: fclib.h:145