fclib.h
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 
87 #ifndef _fclib_h_
88 #define _fclib_h_
89 
90 #ifndef FCLIB_APICOMPILE
91 #define FCLIB_APICOMPILE
92 #endif
93 
94 /* the default is to use a header only library */
95 #ifndef FCLIB_NOT_HEADER_ONLY
96 #define FCLIB_STATIC static
97 #define FCLIB_IMPLEMENTATION
98 #else
99 #define FCLIB_STATIC
100 #endif
101 
102 /* choose api version */
103 #define H5Gcreate_vers 2
104 #define H5Gopen_vers 2
105 
111 {
113  char *title;
115  char *description;
117  char *math_info;
118 };
119 
125 struct FCLIB_APICOMPILE fclib_matrix_info /* matrix information */
126 {
128  char *comment;
130  double conditioning;
132  double determinant;
134  int rank;
135 };
136 
141 {
143  int nzmax ;
145  int m ;
147  int n ;
149  int *p ;
151  int *i ;
153  double *x ;
155  int nz ;
158 };
159 
196 {
198  struct fclib_matrix *M;
200  struct fclib_matrix *H;
202  struct fclib_matrix *G;
204  double *mu;
206  double *f;
208  double *b;
210  double *w;
212  int spacedim;
214  struct fclib_info *info;
215 };
250 {
252  struct fclib_matrix *W;
254  struct fclib_matrix *V;
256  struct fclib_matrix *R;
258  double *mu;
260  double *q;
262  double *s;
264  int spacedim; /* 2 or 3 */
266  struct fclib_info *info;
267 };
268 
275 struct FCLIB_APICOMPILE fclib_solution /* solution data */
276 {
278  double *v;
280  double *u;
282  double *r;
284  double *l;
285 };
286 
290 enum FCLIB_APICOMPILE fclib_merit {MERIT_1, MERIT_2} ; /* merit functions */
291 
294 FCLIB_STATIC int fclib_write_global (struct fclib_global *problem,
295  const char *path);
296 
299 FCLIB_STATIC int fclib_write_local (struct fclib_local *problem,
300  const char *path);
301 
304 FCLIB_STATIC int fclib_write_solution (struct fclib_solution *solution,
305  const char *path);
306 
309 FCLIB_STATIC int fclib_write_guesses (int number_of_guesses,
310  struct fclib_solution *guesses,
311  const char *path);
312 
315 FCLIB_STATIC struct fclib_global* fclib_read_global (const char *path);
316 
319 FCLIB_STATIC struct fclib_local* fclib_read_local (const char *path);
320 
323 FCLIB_STATIC struct fclib_solution* fclib_read_solution (const char *path);
324 
328 FCLIB_STATIC struct fclib_solution* fclib_read_guesses (const char *path,
329  int *number_of_guesses);
330 
331 #ifdef FCLIB_WITH_MERIT_FUNCTIONS
332 
333 FCLIB_STATIC double fclib_merit_global (struct fclib_global *problem,
334  enum fclib_merit merit,
335  struct fclib_solution *solution);
336 
338 FCLIB_STATIC double fclib_merit_local (struct fclib_local *problem,
339  enum fclib_merit merit,
340  struct fclib_solution *solution);
341 #endif
342 
344 FCLIB_STATIC void fclib_delete_global (struct fclib_global *problem);
345 
347 FCLIB_STATIC void fclib_delete_local (struct fclib_local *problem);
348 
351  int count);
352 
355  const char * attr_name,
356  int attr_value);
357 
358 
359 /* ========================= implementation =========================*/
360 
361 #ifdef FCLIB_IMPLEMENTATION
362 
363 #include <string.h>
364 #include <stdlib.h>
365 #include <stdio.h>
366 #include <hdf5.h>
367 #include <hdf5_hl.h>
368 
369 /* useful macros */
370 #define ASSERT(Test, ...)\
371  do {\
372  if (! (Test)) { fprintf (stderr, "%s: %d => ", __FILE__, __LINE__);\
373  fprintf (stderr, __VA_ARGS__);\
374  fprintf (stderr, "\n"); exit (1); } } while (0)
375 
376 #define IO(Call) ASSERT ((Call) >= 0, "ERROR: HDF5 call failed")
377 #define MM(Call) ASSERT ((Call), "ERROR: out of memory")
378 
379 
381 FCLIB_STATIC hid_t H5Gmake (hid_t loc_id, const char *name)
382 {
383  hid_t id;
384 
385  if (H5Lexists (loc_id, name, H5P_DEFAULT))
386  {
387  id = H5Gopen (loc_id, name, H5P_DEFAULT);
388  }
389  else return H5Gcreate (loc_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
390 
391  return id;
392 }
393 
394 
396 FCLIB_STATIC void write_matrix (hid_t id, struct fclib_matrix *mat)
397 {
398  hsize_t dim = 1;
399 
400  IO (H5LTmake_dataset_int (id, "nzmax", 1, &dim, &mat->nzmax));
401  IO (H5LTmake_dataset_int (id, "m", 1, &dim, &mat->m));
402  IO (H5LTmake_dataset_int (id, "n", 1, &dim, &mat->n));
403  IO (H5LTmake_dataset_int (id, "nz", 1, &dim, &mat->nz));
404 
405  if (mat->nz >= 0) /* triplet */
406  {
407  dim = mat->nz;
408  IO (H5LTmake_dataset_int (id, "p", 1, &dim, mat->p));
409  IO (H5LTmake_dataset_int (id, "i", 1, &dim, mat->i));
410  IO (H5LTmake_dataset_double (id, "x", 1, &dim, mat->x));
411  }
412  else if (mat->nz == -1) /* csc */
413  {
414  dim = mat->n+1;
415  IO (H5LTmake_dataset_int (id, "p", 1, &dim, mat->p));
416  dim = mat->nzmax;
417  IO (H5LTmake_dataset_int (id, "i", 1, &dim, mat->i));
418  IO (H5LTmake_dataset_double (id, "x", 1, &dim, mat->x));
419  }
420  else if (mat->nz == -2) /* csr */
421  {
422  dim = mat->m+1;
423  IO (H5LTmake_dataset_int (id, "p", 1, &dim, mat->p));
424  dim = mat->nzmax;
425  IO (H5LTmake_dataset_int (id, "i", 1, &dim, mat->i));
426  IO (H5LTmake_dataset_double (id, "x", 1, &dim, mat->x));
427  }
428  else ASSERT (0, "ERROR: unkown sparse matrix type => fclib_matrix->nz = %d\n", mat->nz);
429 
430  if (mat->info)
431  {
432  dim = 1;
433  if (mat->info->comment) IO (H5LTmake_dataset_string (id, "comment", mat->info->comment));
434  IO (H5LTmake_dataset_double (id, "conditioning", 1, &dim, &mat->info->conditioning));
435  IO (H5LTmake_dataset_double (id, "determinant", 1, &dim, &mat->info->determinant));
436  IO (H5LTmake_dataset_int (id, "rank", 1, &dim, &mat->info->rank));
437  }
438 }
439 
442 {
443  struct fclib_matrix *mat;
444 
445  MM (mat = malloc (sizeof (struct fclib_matrix)));
446 
447  IO (H5LTread_dataset_int (id, "nzmax", &mat->nzmax));
448  IO (H5LTread_dataset_int (id, "m", &mat->m));
449  IO (H5LTread_dataset_int (id, "n", &mat->n));
450  IO (H5LTread_dataset_int (id, "nz", &mat->nz));
451 
452  if (mat->nz >= 0) /* triplet */
453  {
454  MM (mat->p = malloc (sizeof(int)*mat->nz));
455  MM (mat->i = malloc (sizeof(int)*mat->nz));
456  IO (H5LTread_dataset_int (id, "p", mat->p));
457  IO (H5LTread_dataset_int (id, "i", mat->i));
458  }
459  else if (mat->nz == -1) /* csc */
460  {
461  MM (mat->p = malloc (sizeof(int)*(mat->n+1)));
462  MM (mat->i = malloc (sizeof(int)*mat->nzmax));
463  IO (H5LTread_dataset_int (id, "p", mat->p));
464  IO (H5LTread_dataset_int (id, "i", mat->i));
465  }
466  else if (mat->nz == -2) /* csr */
467  {
468  MM (mat->p = malloc (sizeof(int)*(mat->m+1)));
469  MM (mat->i = malloc (sizeof(int)*mat->nzmax));
470  IO (H5LTread_dataset_int (id, "p", mat->p));
471  IO (H5LTread_dataset_int (id, "i", mat->i));
472  }
473  else ASSERT (0, "ERROR: unkown sparse matrix type => fclib_matrix->nz = %d\n", mat->nz);
474 
475  MM (mat->x = malloc (sizeof(double)*mat->nzmax));
476  IO (H5LTread_dataset_double (id, "x", mat->x));
477 
478  if (H5LTfind_dataset (id, "conditioning"))
479  {
480  H5T_class_t class_id;
481  hsize_t dim;
482  size_t size;
483 
484  MM (mat->info = malloc (sizeof (struct fclib_matrix_info)));
485  if (H5LTfind_dataset (id, "comment"))
486  {
487  IO (H5LTget_dataset_info (id, "comment", &dim, &class_id, &size));
488  MM (mat->info->comment = malloc (sizeof(char)*size));
489  IO (H5LTread_dataset_string (id, "comment", mat->info->comment));
490  }
491  else mat->info->comment = NULL;
492  IO (H5LTread_dataset_double (id, "conditioning", &mat->info->conditioning));
493  IO (H5LTread_dataset_double (id, "determinant", &mat->info->determinant));
494  IO (H5LTread_dataset_int (id, "rank", &mat->info->rank));
495  }
496  else
497  {
498  mat->info = NULL;
499  }
500 
501  return mat;
502 }
503 
505 FCLIB_STATIC void write_global_vectors (hid_t id, struct fclib_global *problem)
506 {
507  hsize_t dim;
508 
509  dim = problem->M->m;
510  ASSERT (problem->f, "ERROR: f must be given");
511  IO (H5LTmake_dataset_double (id, "f", 1, &dim, problem->f));
512 
513  dim = problem->H->n;
514  ASSERT (problem->w && problem->mu, "ERROR: w and mu must be given");
515  IO (H5LTmake_dataset_double (id, "w", 1, &dim, problem->w));
516  ASSERT (dim % problem->spacedim == 0, "ERROR: number of H columns is not divisble by the spatial dimension");
517  dim /= problem->spacedim;
518  IO (H5LTmake_dataset_double (id, "mu", 1, &dim, problem->mu));
519 
520  if (problem->G)
521  {
522  dim = problem->G->n;
523  ASSERT (problem->b, "ERROR: b must be given if G is present");
524  IO (H5LTmake_dataset_double (id, "b", 1, &dim, problem->b));
525  }
526 }
527 
529 FCLIB_STATIC void read_global_vectors (hid_t id, struct fclib_global *problem)
530 {
531  MM (problem->f = malloc (sizeof(double)*problem->M->m));
532  IO (H5LTread_dataset_double (id, "f", problem->f));
533 
534  ASSERT (problem->H->n % problem->spacedim == 0, "ERROR: number of H columns is not divisble by the spatial dimension");
535  MM (problem->w = malloc (sizeof(double)*problem->H->n));
536  MM (problem->mu = malloc (sizeof(double)*(problem->H->n / problem->spacedim)));
537  IO (H5LTread_dataset_double (id, "w", problem->w));
538  IO (H5LTread_dataset_double (id, "mu", problem->mu));
539 
540  if (problem->G)
541  {
542  MM (problem->b = malloc (sizeof(double)*problem->G->n));
543  IO (H5LTread_dataset_double (id, "b", problem->b));
544  }
545 }
546 
548 FCLIB_STATIC void write_local_vectors (hid_t id, struct fclib_local *problem)
549 {
550  hsize_t dim;
551 
552  dim = problem->W->m;
553  ASSERT (problem->q, "ERROR: q must be given");
554  IO (H5LTmake_dataset_double (id, "q", 1, &dim, problem->q));
555 
556  ASSERT (dim % problem->spacedim == 0, "ERROR: number of W rows is not divisble by the spatial dimension");
557  dim /= problem->spacedim;
558  IO (H5LTmake_dataset_double (id, "mu", 1, &dim, problem->mu));
559 
560  if (problem->V)
561  {
562  dim = problem->R->m;
563  ASSERT (problem->s, "ERROR: s must be given if R is present");
564  IO (H5LTmake_dataset_double (id, "s", 1, &dim, problem->s));
565  }
566 }
567 
569 FCLIB_STATIC void read_local_vectors (hid_t id, struct fclib_local *problem)
570 {
571  MM (problem->q = malloc (sizeof(double)*problem->W->m));
572  IO (H5LTread_dataset_double (id, "q", problem->q));
573 
574  ASSERT (problem->W->m % problem->spacedim == 0, "ERROR: number of W rows is not divisble by the spatial dimension");
575  MM (problem->mu = malloc (sizeof(double)*(problem->W->m / problem->spacedim)));
576  IO (H5LTread_dataset_double (id, "mu", problem->mu));
577 
578  if (problem->R)
579  {
580  MM (problem->s = malloc (sizeof(double)*problem->R->m));
581  IO (H5LTread_dataset_double (id, "s", problem->s));
582  }
583 }
584 
587 {
588  if (info->title) IO (H5LTmake_dataset_string (id, "title", info->title));
589  if (info->description) IO (H5LTmake_dataset_string (id, "description", info->description));
590  if (info->math_info) IO (H5LTmake_dataset_string (id, "math_info", info->math_info));
591 }
592 
595 {
596  struct fclib_info *info;
597  H5T_class_t class_id;
598  hsize_t dim;
599  size_t size;
600 
601  MM (info = malloc (sizeof (struct fclib_info)));
602 
603  if (H5LTfind_dataset (id, "title"))
604  {
605  IO (H5LTget_dataset_info (id, "title", &dim, &class_id, &size));
606  MM (info->title = malloc (sizeof(char)*size));
607  IO (H5LTread_dataset_string (id, "title", info->title));
608  }
609  else info->title = NULL;
610 
611  if (H5LTfind_dataset (id, "description"))
612  {
613  IO (H5LTget_dataset_info (id, "description", &dim, &class_id, &size));
614  MM (info->description = malloc (sizeof(char)*size));
615  IO (H5LTread_dataset_string (id, "description", info->description));
616  }
617  else info->description = NULL;
618 
619  if (H5LTfind_dataset (id, "math_info"))
620  {
621  IO (H5LTget_dataset_info (id, "math_info", &dim, &class_id, &size));
622  MM (info->math_info = malloc (sizeof(char)*size));
623  IO (H5LTread_dataset_string (id, "math_info", info->math_info));
624  }
625  else info->math_info = NULL;
626 
627  return info;
628 }
629 
631 FCLIB_STATIC void write_solution (hid_t id, struct fclib_solution *solution, hsize_t nv, hsize_t nr, hsize_t nl)
632 {
633  if (nv) IO (H5LTmake_dataset_double (id, "v", 1, &nv, solution->v));
634  if (nl) IO (H5LTmake_dataset_double (id, "l", 1, &nl, solution->l));
635 
636  ASSERT (nr, "ERROR: contact constraints must be present");
637  IO (H5LTmake_dataset_double (id, "u", 1, &nr, solution->u));
638  IO (H5LTmake_dataset_double (id, "r", 1, &nr, solution->r));
639 }
640 
642 FCLIB_STATIC void read_solution (hid_t id, hsize_t nv, hsize_t nr, hsize_t nl, struct fclib_solution *solution)
643 {
644  if (nv)
645  {
646  MM (solution->v = malloc (sizeof(double)*nv));
647  IO (H5LTread_dataset_double (id, "v", solution->v));
648  }
649  else solution->v = NULL;
650 
651  if (nl)
652  {
653  MM (solution->l = malloc (sizeof(double)*nl));
654  IO (H5LTread_dataset_double (id, "l", solution->l));
655  }
656  else solution->l = NULL;
657 
658  ASSERT (nr, "ERROR: contact constraints must be present");
659  MM (solution->u = malloc (sizeof(double)*nr));
660  IO (H5LTread_dataset_double (id, "u", solution->u));
661  MM (solution->r = malloc (sizeof(double)*nr));
662  IO (H5LTread_dataset_double (id, "r", solution->r));
663 }
664 
666 FCLIB_STATIC int read_nvnunrnl (hid_t file_id, int *nv, int *nr, int *nl)
667 {
668  if (H5Lexists (file_id, "/fclib_global", H5P_DEFAULT))
669  {
670  IO (H5LTread_dataset_int (file_id, "/fclib_global/M/n", nv));
671  IO (H5LTread_dataset_int (file_id, "/fclib_global/H/n", nr));
672  if (H5Lexists (file_id, "/fclib_global/G", H5P_DEFAULT))
673  {
674  IO (H5LTread_dataset_int (file_id, "/fclib_global/G/n", nl));
675  }
676  else *nl = 0;
677  }
678  else if (H5Lexists (file_id, "/fclib_local", H5P_DEFAULT))
679  {
680  *nv = 0;
681  IO (H5LTread_dataset_int (file_id, "/fclib_local/W/n", nr));
682  if (H5Lexists (file_id, "/fclib_local/R", H5P_DEFAULT))
683  {
684  IO (H5LTread_dataset_int (file_id, "/fclib_local/R/n", nl));
685  }
686  else *nl = 0;
687  }
688  else
689  {
690  fprintf (stderr, "ERROR: neither global nor local problem has been stored. Global or local have to be stored before solutions or guesses\n");
691  return 0;
692  }
693 
694  return 1;
695 }
696 
699 {
700  if (info)
701  {
702  free (info->comment);
703  free (info);
704  }
705 }
706 
709 {
710  if (mat)
711  {
712  free (mat->p);
713  free (mat->i);
714  free (mat->x);
715  delete_matrix_info (mat->info);
716  free (mat);
717  }
718 }
719 
722 {
723  if (info)
724  {
725  if (info->title) free (info->title);
726  if (info->description) free (info->description);
727  if (info->math_info) free (info->math_info);
728  free(info);
729  }
730 }
731 
732 FCLIB_STATIC int FCLIB_APICOMPILE fclib_create_int_attributes_in_info(const char *path, const char * attr_name,
733  int attr_value)
734 {
735  hid_t file_id, id, dataspace_id, attr_id;
736  hsize_t dim = 1;
737  hsize_t dims[1];
738  FILE *f;
739 
740  if ((f = fopen (path, "r"))) /* HDF5 outputs lots of warnings when file does not exist */
741  {
742  fclose (f);
743  if ((file_id = H5Fopen (path, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
744  {
745  fprintf (stderr, "ERROR: opening file failed\n");
746  return 0;
747  }
748  }
749 
750  if (H5Lexists (file_id, "/fclib_local/info", H5P_DEFAULT))
751  {
752  IO (id = H5Gopen (file_id, "/fclib_local/info", H5P_DEFAULT));
753  dims[0]=1;
754  dataspace_id = H5Screate_simple(1, dims, NULL);
755  attr_id = H5Acreate (id, attr_name, H5T_NATIVE_INT, dataspace_id,
756  H5P_DEFAULT, H5P_DEFAULT);
757  IO(H5Awrite(attr_id, H5T_NATIVE_INT , &attr_value ));
758  IO(H5Aclose (attr_id));
759  IO (H5Gclose (id));
760  }
761  else
762  {
763  IO (id = H5Gmake (file_id, "/fclib_local/info"));
764  dims[0]=1;
765  dataspace_id = H5Screate_simple(1, dims, NULL);
766  attr_id = H5Acreate (id, attr_name, H5T_NATIVE_INT, dataspace_id,
767  H5P_DEFAULT, H5P_DEFAULT);
768  IO(H5Awrite(attr_id, H5T_NATIVE_INT , &attr_value ));
769  IO(H5Aclose (attr_id));
770  IO (H5Gclose (id));
771  }
772  IO (H5Fclose (file_id));
773 
774  return 1;
775 }
776 
777 /* =========================== interface ============================ */
778 
781 FCLIB_STATIC int FCLIB_APICOMPILE fclib_write_global (struct fclib_global *problem, const char *path)
782 {
783  hid_t file_id, main_id, id;
784  hsize_t dim = 1;
785  FILE *f;
786 
787  if ((f = fopen (path, "r"))) /* HDF5 outputs lots of warnings when file does not exist */
788  {
789  fclose (f);
790  if ((file_id = H5Fopen (path, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
791  {
792  fprintf (stderr, "ERROR: opening file failed\n");
793  return 0;
794  }
795 
796  if (H5Lexists (file_id, "/fclib_global", H5P_DEFAULT)) /* cannot overwrite existing datasets */
797  {
798  fprintf (stderr, "ERROR: a global problem has already been written to this file\n");
799  return 0;
800  }
801  }
802  else if ((file_id = H5Fcreate (path, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) /* cerate */
803  {
804  fprintf (stderr, "ERROR: creating file failed\n");
805  return 0;
806  }
807 
808  IO (main_id = H5Gmake (file_id, "/fclib_global"));
809 
810  ASSERT (problem->spacedim == 2 || problem->spacedim == 3, "ERROR: space dimension must be 2 or 3");
811  IO (H5LTmake_dataset_int (file_id, "/fclib_global/spacedim", 1, &dim, &problem->spacedim));
812 
813  ASSERT (problem->M, "ERROR: M must be given");
814  IO (id = H5Gmake (file_id, "/fclib_global/M"));
815  write_matrix (id, problem->M);
816  IO (H5Gclose (id));
817 
818  ASSERT (problem->H, "ERROR: H must be given");
819  IO (id = H5Gmake (file_id, "/fclib_global/H"));
820  write_matrix (id, problem->H);
821  IO (H5Gclose (id));
822 
823  if (problem->G)
824  {
825  IO (id = H5Gmake (file_id, "/fclib_global/G"));
826  write_matrix (id, problem->G);
827  IO (H5Gclose (id));
828  }
829 
830  IO (id = H5Gmake (file_id, "/fclib_global/vectors"));
831  write_global_vectors (id, problem);
832  IO (H5Gclose (id));
833 
834  if (problem->info)
835  {
836  IO (id = H5Gmake (file_id, "/fclib_global/info"));
837  write_problem_info (id, problem->info);
838  IO (H5Gclose (id));
839  }
840 
841  IO (H5Gclose (main_id));
842  IO (H5Fclose (file_id));
843 
844  return 1;
845 }
846 
847 
848 
849 
850 
853 FCLIB_STATIC int FCLIB_APICOMPILE fclib_write_local (struct fclib_local *problem, const char *path)
854 {
855  hid_t file_id, main_id, id;
856  hsize_t dim = 1;
857  FILE *f;
858 
859  if ((f = fopen (path, "r"))) /* HDF5 outputs lots of warnings when file does not exist */
860  {
861  fclose (f);
862  if ((file_id = H5Fopen (path, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
863  {
864  fprintf (stderr, "ERROR: opening file failed\n");
865  return 0;
866  }
867 
868  if (H5Lexists (file_id, "/fclib_local", H5P_DEFAULT)) /* cannot overwrite existing datasets */
869  {
870  fprintf (stderr, "ERROR: a local problem has already been written to this file\n");
871  return 0;
872  }
873  }
874  else if ((file_id = H5Fcreate (path, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) /* cerate */
875  {
876  fprintf (stderr, "ERROR: creating file failed\n");
877  return 0;
878  }
879 
880  IO (main_id = H5Gmake (file_id, "/fclib_local"));
881 
882  ASSERT (problem->spacedim == 2 || problem->spacedim == 3, "ERROR: space dimension must be 2 or 3");
883  IO (H5LTmake_dataset_int (file_id, "/fclib_local/spacedim", 1, &dim, &problem->spacedim));
884 
885  ASSERT (problem->W, "ERROR: W must be given");
886  IO (id = H5Gmake (file_id, "/fclib_local/W"));
887  write_matrix (id, problem->W);
888  IO (H5Gclose (id));
889 
890  if (problem->V && problem->R)
891  {
892  IO (id = H5Gmake (file_id, "/fclib_local/V"));
893  write_matrix (id, problem->V);
894  IO (H5Gclose (id));
895 
896  IO (id = H5Gmake (file_id, "/fclib_local/R"));
897  write_matrix (id, problem->R);
898  IO (H5Gclose (id));
899  }
900  else ASSERT (!problem->V && !problem->R, "ERROR: V and R must be defined at the same time");
901 
902  IO (id = H5Gmake (file_id, "/fclib_local/vectors"));
903  write_local_vectors (id, problem);
904  IO (H5Gclose (id));
905 
906  if (problem->info)
907  {
908  IO (id = H5Gmake (file_id, "/fclib_local/info"));
909  write_problem_info (id, problem->info);
910  IO (H5Gclose (id));
911  }
912 
913  IO (H5Gclose (main_id));
914  IO (H5Fclose (file_id));
915 
916  return 1;
917 }
918 
921 FCLIB_STATIC int FCLIB_APICOMPILE fclib_write_solution (struct fclib_solution *solution, const char *path)
922 {
923  hid_t file_id, id;
924  int nv, nr, nl;
925  FILE *f;
926 
927  if ((f = fopen (path, "r"))) /* HDF5 outputs lots of warnings when file does not exist */
928  {
929  fclose (f);
930  if ((file_id = H5Fopen (path, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
931  {
932  fprintf (stderr, "ERROR: opening file failed\n");
933  return 0;
934  }
935 
936  if (H5Lexists (file_id, "/solution", H5P_DEFAULT)) /* cannot overwrite existing datasets */
937  {
938  fprintf (stderr, "ERROR: a solution has already been written to this file\n");
939  return 0;
940  }
941  }
942  else
943  {
944  fprintf (stderr, "ERROR: opening file failed\n");
945  return 0;
946  }
947 
948  if (! read_nvnunrnl (file_id, &nv, &nr, &nl)) return 0;
949 
950  IO (id = H5Gmake (file_id, "/solution"));
951  write_solution (id, solution, nv, nr, nl);
952  IO (H5Gclose (id));
953 
954  IO (H5Fclose (file_id));
955 
956  return 1;
957 }
958 
961 FCLIB_STATIC int FCLIB_APICOMPILE fclib_write_guesses (int number_of_guesses, struct fclib_solution *guesses, const char *path)
962 {
963  hid_t file_id, main_id, id;
964  int nv, nr, nl, i;
965  hsize_t dim = 1;
966  char num [128];
967  FILE *f;
968 
969  if ((f = fopen (path, "r"))) /* HDF5 outputs lots of warnings when file does not exist */
970  {
971  fclose (f);
972  if ((file_id = H5Fopen (path, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
973  {
974  fprintf (stderr, "ERROR: opening file failed\n");
975  return 0;
976  }
977 
978  if (H5Lexists (file_id, "/guesses", H5P_DEFAULT)) /* cannot overwrite existing datasets */
979  {
980  fprintf (stderr, "ERROR: some guesses have already been written to this file\n");
981  return 0;
982  }
983  }
984  else
985  {
986  fprintf (stderr, "ERROR: opening file failed\n");
987  return 0;
988  }
989 
990  if (! read_nvnunrnl (file_id, &nv, &nr, &nl)) return 0;
991 
992  IO (main_id = H5Gmake (file_id, "/guesses"));
993  IO (H5LTmake_dataset_int (file_id, "/guesses/number_of_guesses", 1, &dim, &number_of_guesses));
994 
995  for (i = 0; i < number_of_guesses; i ++)
996  {
997  snprintf (num, 128, "%d", i+1);
998  IO (id = H5Gmake (main_id, num));
999  write_solution (id, &guesses [i], nv, nr, nl);
1000  IO (H5Gclose (id));
1001  }
1002 
1003  IO (H5Gclose (main_id));
1004  IO (H5Fclose (file_id));
1005 
1006  return 1;
1007 }
1008 
1012 {
1013  struct fclib_global *problem;
1014  hid_t file_id, main_id, id;
1015 
1016  if ((file_id = H5Fopen (path, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
1017  {
1018  fprintf (stderr, "ERROR: opening file failed\n");
1019  return NULL;
1020  }
1021 
1022  MM (problem = calloc (1, sizeof (struct fclib_global)));
1023 
1024  IO (main_id = H5Gopen (file_id, "/fclib_global", H5P_DEFAULT));
1025  IO (H5LTread_dataset_int (file_id, "/fclib_global/spacedim", &problem->spacedim));
1026 
1027  IO (id = H5Gopen (file_id, "/fclib_global/M", H5P_DEFAULT));
1028  problem->M = read_matrix (id);
1029  IO (H5Gclose (id));
1030 
1031  IO (id = H5Gopen (file_id, "/fclib_global/H", H5P_DEFAULT));
1032  problem->H = read_matrix (id);
1033  IO (H5Gclose (id));
1034 
1035  if (H5Lexists (file_id, "/fclib_global/G", H5P_DEFAULT))
1036  {
1037  IO (id = H5Gopen (file_id, "/fclib_global/G", H5P_DEFAULT));
1038  problem->G = read_matrix (id);
1039  IO (H5Gclose (id));
1040  }
1041 
1042  IO (id = H5Gopen (file_id, "/fclib_global/vectors", H5P_DEFAULT));
1043  read_global_vectors (id, problem);
1044  IO (H5Gclose (id));
1045 
1046  if (H5Lexists (file_id, "/fclib_global/info", H5P_DEFAULT))
1047  {
1048  IO (id = H5Gopen (file_id, "/fclib_global/info", H5P_DEFAULT));
1049  problem->info = read_problem_info (id);
1050  IO (H5Gclose (id));
1051  }
1052 
1053  IO (H5Gclose (main_id));
1054  IO (H5Fclose (file_id));
1055 
1056  return problem;
1057 }
1058 
1062 {
1063  struct fclib_local *problem;
1064  hid_t file_id, main_id, id;
1065 
1066  if ((file_id = H5Fopen (path, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
1067  {
1068  fprintf (stderr, "ERROR: opening file failed\n");
1069  return NULL;
1070  }
1071 
1072  if (!H5Lexists (file_id, "/fclib_local", H5P_DEFAULT))
1073  {
1074  fprintf (stderr, "ERROR: spurious input file %s :: fclib_local group does not exists", path);
1075  return NULL;
1076  }
1077 
1078  MM (problem = calloc (1, sizeof (struct fclib_local)));
1079 
1080  IO (main_id = H5Gopen (file_id, "/fclib_local", H5P_DEFAULT));
1081  IO (H5LTread_dataset_int (file_id, "/fclib_local/spacedim", &problem->spacedim));
1082 
1083  IO (id = H5Gopen (file_id, "/fclib_local/W", H5P_DEFAULT));
1084  problem->W = read_matrix (id);
1085  IO (H5Gclose (id));
1086 
1087  if (H5Lexists (file_id, "/fclib_local/V", H5P_DEFAULT))
1088  {
1089  IO (id = H5Gopen (file_id, "/fclib_local/V", H5P_DEFAULT));
1090  problem->V = read_matrix (id);
1091  IO (H5Gclose (id));
1092 
1093  IO (id = H5Gopen (file_id, "/fclib_local/R", H5P_DEFAULT));
1094  problem->R = read_matrix (id);
1095  IO (H5Gclose (id));
1096  }
1097 
1098  IO (id = H5Gopen (file_id, "/fclib_local/vectors", H5P_DEFAULT));
1099  read_local_vectors (id, problem);
1100  IO (H5Gclose (id));
1101 
1102  if (H5Lexists (file_id, "/fclib_local/info", H5P_DEFAULT))
1103  {
1104  IO (id = H5Gopen (file_id, "/fclib_local/info", H5P_DEFAULT));
1105  problem->info = read_problem_info (id);
1106  IO (H5Gclose (id));
1107  }
1108 
1109  IO (H5Gclose (main_id));
1110  IO (H5Fclose (file_id));
1111 
1112  return problem;
1113 }
1114 
1118 {
1119  struct fclib_solution *solution;
1120  hid_t file_id, id;
1121  int nv, nr, nl;
1122 
1123  if ((file_id = H5Fopen (path, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) /* overwrite */
1124  {
1125  fprintf (stderr, "ERROR: opening file failed\n");
1126  return 0;
1127  }
1128 
1129  MM (solution = malloc (sizeof (struct fclib_solution)));
1130 
1131  if (! read_nvnunrnl (file_id, &nv, &nr, &nl)) return 0;
1132 
1133  IO (id = H5Gopen (file_id, "/solution", H5P_DEFAULT));
1134  read_solution (id, nv, nr, nl, solution);
1135  IO (H5Gclose (id));
1136 
1137  IO (H5Fclose (file_id));
1138 
1139  return solution;
1140 }
1141 
1145 FCLIB_STATIC struct FCLIB_APICOMPILE fclib_solution* fclib_read_guesses (const char *path, int *number_of_guesses)
1146 {
1147  struct fclib_solution *guesses;
1148  hid_t file_id, main_id, id;
1149  int nv, nr, nl, i;
1150  char num [128];
1151 
1152  if ((file_id = H5Fopen (path, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) /* overwrite */
1153  {
1154  fprintf (stderr, "ERROR: opening file failed\n");
1155  return 0;
1156  }
1157 
1158  if (! read_nvnunrnl (file_id, &nv, &nr, &nl)) return 0;
1159 
1160  if (H5Lexists (file_id, "/guesses", H5P_DEFAULT))
1161  {
1162  IO (main_id = H5Gopen (file_id, "/guesses", H5P_DEFAULT));
1163 
1164  IO (H5LTread_dataset_int (file_id, "/guesses/number_of_guesses", number_of_guesses));
1165 
1166  MM (guesses = malloc ((*number_of_guesses) * sizeof (struct fclib_solution)));
1167 
1168  for (i = 0; i < *number_of_guesses; i ++)
1169  {
1170  snprintf (num, 128, "%d", i+1);
1171  IO (id = H5Gopen (main_id, num, H5P_DEFAULT));
1172  read_solution (id, nv, nr, nl, &guesses [i]);
1173  IO (H5Gclose (id));
1174  }
1175 
1176  IO (H5Gclose (main_id));
1177  }
1178 
1179  IO (H5Fclose (file_id));
1180 
1181  return guesses;
1182 }
1183 
1186 {
1187  delete_matrix (problem->M);
1188  delete_matrix (problem->H);
1189  delete_matrix (problem->G);
1190  free (problem->mu);
1191  free (problem->f);
1192  if (problem->b) free (problem->b);
1193  free (problem->w);
1194  delete_info (problem->info);
1195 }
1196 
1199 {
1200  delete_matrix (problem->W);
1201  delete_matrix (problem->V);
1202  delete_matrix (problem->R);
1203  free (problem->mu);
1204  free (problem->q);
1205  if (problem->s) free (problem->s);
1206  delete_info (problem->info);
1207 }
1208 
1211 {
1212  int i;
1213 
1214  for (i = 0; i < count; i ++)
1215  {
1216  if (data [i].v) free (data [i].v);
1217  if (data [i].u) free (data [i].u);
1218  if (data [i].r) free (data [i].r);
1219  if (data [i].l) free (data [i].l);
1220  }
1221 
1222  free (data);
1223 }
1224 
1225 #ifdef FCLIB_WITH_MERIT_FUNCTIONS
1226 #include "csparse.h"
1227 
1228 
1229 FCLIB_STATIC inline double dnrm2(double * v , int n)
1230 {
1231  int i;
1232  double norm2=0.0;
1233  for (i=0; i <n ; i++) norm2 += v[i]*v[i];
1234  return sqrt(norm2);
1235 }
1236 
1237 FCLIB_STATIC inline void projectionOnCone(double* r, double mu)
1238 {
1239  double normT = hypot(r[1], r[2]);
1240  if (mu * normT <= - r[0])
1241  {
1242  r[0] = 0.0;
1243  r[1] = 0.0;
1244  r[2] = 0.0;
1245  return ;
1246  }
1247  else if (normT <= mu * r[0])
1248  {
1249  return ;
1250  }
1251  else
1252  {
1253  double mu2 = mu * mu;
1254  r[0] = (mu * normT + r[0]) / (mu2 + 1.0);
1255  r[1] = mu * r[0] * r[1] / normT;
1256  r[2] = mu * r[0] * r[2] / normT;
1257  return;
1258  }
1259 }
1260 
1261 FCLIB_STATIC void FrictionContact3D_unitary_compute_and_add_error(double *z , double *w, double mu, double * error)
1262 {
1263 
1264  double normUT;
1265  double worktmp[3];
1266  /* Compute the modified local velocity */
1267  normUT = hypot(w[1], w[2]); // i.e sqrt(w[ic3p1]*w[ic3p1]+w[ic3p2]*w[ic3p2]);
1268  worktmp[0] = z[0] - (w[0] + mu * normUT);
1269  worktmp[1] = z[1] - w[1] ;
1270  worktmp[2] = z[2] - w[2] ;
1271  projectionOnCone(worktmp, mu);
1272  worktmp[0] = z[0] - worktmp[0];
1273  worktmp[1] = z[1] - worktmp[1];
1274  worktmp[2] = z[2] - worktmp[2];
1275  *error += worktmp[0] * worktmp[0] + worktmp[1] * worktmp[1] + worktmp[2] * worktmp[2];
1276 
1277 }
1278 
1279 /* calculate merit function for a global problem */
1280 FCLIB_STATIC double fclib_merit_global (struct fclib_global *problem, enum fclib_merit merit, struct fclib_solution *solution)
1281 {
1282  return 0; /* TODO */
1283 }
1284 
1285 /* calculate merit function for a local problem */
1286 FCLIB_STATIC double fclib_merit_local (struct fclib_local *problem, enum fclib_merit merit, struct fclib_solution *solution)
1287 {
1288 
1289  struct fclib_matrix * W = problem->W;
1290  struct fclib_matrix * V = problem->V;
1291  struct fclib_matrix * R = problem->R;
1292 
1293  double *mu = problem->mu;
1294  double *q = problem->q;
1295  double *s = problem->s;
1296  int d = problem->spacedim;
1297  if (d !=3 )
1298  {
1299  printf("fclib_merit_local for space dimension = %i not yet implemented\n",d);
1300  return 0;
1301  }
1302 
1303  double *v = solution->v;
1304  double *r = solution->r;
1305  double *u = solution->u;
1306  double *l = solution->l;
1307 
1308  double error_l, error;
1309  double * tmp;
1310 
1311  error=0.0;
1312  error_l=0.0;
1313  int i, ic, ic3;
1314  if (merit == MERIT_1)
1315  {
1316 
1317  /* cs M_cs; */
1318  /* fclib_matrix_to_cssparse(W, &M_cs); */
1319  /* cs V_cs; */
1320  /* fclib_matrix_to_cssparse(V, &V_cs); */
1321  /* cs R_cs; */
1322  /* fclib_matrix_to_cssparse(R, &R_cs); */
1323  int n_e =0;
1324  if (R) n_e = R->n;
1325  /* compute V^T {r} + R \lambda + s */
1326  if (n_e >0)
1327  {
1328  cs * VT = cs_transpose((cs *)V, 0) ;
1329  tmp = (double *)malloc(n_e*sizeof(double));
1330  for (i =0; i <n_e; i++) tmp[i] = s[i] ;
1331  cs_gaxpy(VT, r, tmp);
1332  cs_gaxpy((cs *)R, l, tmp);
1333  error_l += dnrm2(tmp,n_e)/(1.0 + dnrm2(s,n_e) );
1334  free(tmp);
1335  }
1336  /* compute \hat u = W {r} + V\lambda + q */
1337 
1338  tmp = (double *)malloc(W->n*sizeof(double));
1339  for (i =0; i <W->n; i++) tmp[i] = q[i] ;
1340  cs_gaxpy((cs*)V, l, tmp);
1341  cs_gaxpy((cs*)W, r, tmp);
1342 
1343  /* Compute natural map */
1344  int nc = W->n/3;
1345  for (ic = 0, ic3 = 0 ; ic < nc ; ic++, ic3 += 3)
1346  {
1347  FrictionContact3D_unitary_compute_and_add_error(r + ic3, tmp + ic3, mu[ic], &error);
1348  }
1349 
1350  free(tmp);
1351  error = sqrt(error)/(1.0 + sqrt(dnrm2(q,W->n)) )+error_l;
1352 
1353  /* printf("error_l = %12.8e", error_l); */
1354  /* printf("norm of u = %12.8e\n", dnrm2(u,W->n)); */
1355  /* printf("norm of r = %12.8e\n", dnrm2(r,W->n)); */
1356  /* printf("error = %12.8e\n", error); */
1357 
1358  return error;
1359  }
1360 
1361  return 0; /* TODO */
1362 }
1363 #endif /* FCLIB_WITH_MERIT_FUNCTIONS */
1364 
1365 #endif /* FCLIB_IMPLEMENTATION */
1366 
1367 #endif /* _fclib_h_ */
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
FCLIB_STATIC void write_local_vectors(hid_t id, struct fclib_local *problem)
write local vectors
Definition: fclib.h:548
FCLIB_STATIC hid_t H5Gmake(hid_t loc_id, const char *name)
make group
Definition: fclib.h:381
enum FCLIB_APICOMPILE fclib_merit
Definition: fclib.h:290
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
FCLIB_STATIC int fclib_write_local(struct fclib_local *problem, const char *path)
write local problem; return 1 on success, 0 on failure
Definition: fclib.h:853
FCLIB_STATIC void delete_matrix_info(struct fclib_matrix_info *info)
delete matrix info
Definition: fclib.h:698
struct fclib_matrix * V
the matrix V (see mathematical description below)
Definition: fclib.h:254
#define ASSERT(Test,...)
Definition: fclib.h:370
MERIT_1
Definition: fclib.h:290
#define IO(Call)
Definition: fclib.h:376
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
FCLIB_STATIC void write_problem_info(hid_t id, struct fclib_info *info)
write problem info
Definition: fclib.h:586
FCLIB_STATIC void read_local_vectors(hid_t id, struct fclib_local *problem)
read local vectors
Definition: fclib.h:569
FCLIB_STATIC void write_global_vectors(hid_t id, struct fclib_global *problem)
write global vectors
Definition: fclib.h:505
#define FCLIB_STATIC
Definition: fclib.h:96
FCLIB_STATIC void delete_matrix(struct fclib_matrix *mat)
delete matrix
Definition: fclib.h:708
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
FCLIB_STATIC int read_nvnunrnl(hid_t file_id, int *nv, int *nr, int *nl)
read solution sizes
Definition: fclib.h:666
FCLIB_STATIC void read_solution(hid_t id, hsize_t nv, hsize_t nr, hsize_t nl, struct fclib_solution *solution)
read solution
Definition: fclib.h:642
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
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
double * f
the vector f (see mathematical description below)
Definition: fclib.h:206
#define MM(Call)
Definition: fclib.h:377
FCLIB_STATIC void write_solution(hid_t id, struct fclib_solution *solution, hsize_t nv, hsize_t nr, hsize_t nl)
write solution
Definition: fclib.h:631
double * b
the vector b (see mathematical description below)
Definition: fclib.h:208
FCLIB_STATIC void read_global_vectors(hid_t id, struct fclib_global *problem)
read global vectors
Definition: fclib.h:529
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
struct fclib_matrix * H
the matrix M (see mathematical description below)
Definition: fclib.h:200
FCLIB_STATIC void write_matrix(hid_t id, struct fclib_matrix *mat)
write matrix
Definition: fclib.h:396
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
FCLIB_STATIC struct fclib_info * read_problem_info(hid_t id)
read problem info
Definition: fclib.h:594
struct fclib_info * info
info on the problem
Definition: fclib.h:214
#define FCLIB_APICOMPILE
Definition: fclib.h:91
double * v
global velocity (or position/displacement for quasi-static problems) solution vector ...
Definition: fclib.h:278
FCLIB_STATIC int fclib_create_int_attributes_in_info(const char *path, const char *attr_name, int attr_value)
create and set attributes of tyoe int in info
Definition: fclib.h:732
char * comment
comment on the matrix properties
Definition: fclib.h:128
FCLIB_STATIC int fclib_write_guesses(int number_of_guesses, struct fclib_solution *guesses, const char *path)
write initial guesses; return 1 on success, 0 on failure
Definition: fclib.h:961
double * mu
the vector of coefficient of friction (see mathematical description below)
Definition: fclib.h:258
FCLIB_STATIC struct fclib_matrix * read_matrix(hid_t id)
read matrix
Definition: fclib.h:441
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
FCLIB_STATIC int fclib_write_global(struct fclib_global *problem, const char *path)
write global problem; return 1 on success, 0 on failure
Definition: fclib.h:781
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
FCLIB_STATIC void delete_info(struct fclib_info *info)
delete problem info
Definition: fclib.h:721
struct fclib_matrix_info * info
info for this matrix
Definition: fclib.h:157
FCLIB_STATIC int fclib_write_solution(struct fclib_solution *solution, const char *path)
write solution; return 1 on success, 0 on failure
Definition: fclib.h:921
int m
number of rows
Definition: fclib.h:145