Flow123d
solve.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2007 Technical University of Liberec. All rights reserved.
4  *
5  * Please make a following refer to Flow123d on your project site if you use the program for any purpose,
6  * especially for academic research:
7  * Flow123d, Research Centre: Advanced Remedial Technologies, Technical University of Liberec, Czech Republic
8  *
9  * This program is free software; you can redistribute it and/or modify it under the terms
10  * of the GNU General Public License version 3 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along with this program; if not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 021110-1307, USA.
18  *
19  *
20  * $Id$
21  * $Revision$
22  * $LastChangedBy$
23  * $LastChangedDate$
24  *
25  * @file
26  * @ingroup la
27  * @brief Unified interface to various linear solvers
28  * @author Jan Brezina
29  *
30  * The only internal (linked) solver is PETSC KPS which is already interface to the number of direct
31  * and iterative solvers. Further several external solvers are supported: MATLAB, ISOL (due to Pavel Jiranek)
32  */
33 
34 #include <ctype.h>
35 #include <strings.h>
36 //#include <petscksp.h>
37 //#include <petscviewer.h>
38 
39 #include "system/system.hh"
40 #include "system/sys_profiler.hh"
41 #include "system/xio.h"
42 #include "input/input_type.hh"
43 #include "input/accessors.hh"
44 
45 
46 #include "la/distribution.hh"
47 #include "la/solve.h"
48 #include "la/linsys.hh"
49 
50 //#include "profiler.hh"
51 
52 static void solver_set_type( struct Solver *solver );
53 static void RunExtern( struct Solver *solver,char *cmdline,void (*write_sys)(struct Solver *), void (*read_sol)(struct Solver *) );
54 static void clean_directory(void);
55 
56 // internal solvers
57 //static void solver_petsc(struct Solver *solver);
58 
59 // drivers for external solvers
60 // MATLAB
61 static void write_sys_matlab( struct Solver *solver );
62 static void write_matlab_linsys(LinSys *mtx,int nz);
63 static void read_sol_matlab( struct Solver *solver );
64 // ISOL
65 static void isol_params_init(ISOL_params *par);
66 static void write_sys_isol( struct Solver *solver );
67 
68 
69 namespace it = Input::Type;
70 
71 it::AbstractRecord Solver::input_type = it::AbstractRecord("Solver", "Solver setting.")
72  .declare_key("a_tol", it::Double(0.0), it::Default("1.0e-9"),
73  "Absolute residual tolerance.")
74  .declare_key("r_tol", it::Double(0.0, 1.0), it::Default("1.0e-7"),
75  "Relative residual tolerance (to initial error).")
76  .declare_key("max_it", it::Integer(0), it::Default("10000"),
77  "Maximum number of outer iterations of the linear solver.");
78 
79 
80 it::Record Solver::input_type_petsc = it::Record("Petsc", "Solver setting.")
81  .derive_from(Solver::input_type)
82  .declare_key("options", it::String(), it::Default(""), "Options passed to the petsc instead of default setting.");
83 
84 
85 it::Record Solver::input_type_bddc = it::Record("Bddc", "Solver setting.")
86  .derive_from(Solver::input_type);
87 
88 
89 
90 //==============================================================================
91 /*! @brief Initialize a solver structure
92  *
93  * Initialize all members form the users options.
94  * Possibly initialize specific solver parameters.
95  *
96  * @param[in] solver already allocated structure to be initialized
97  * @param[in] in_rec input record
98  */
99 void solver_init(Solver * solver, Input::AbstractRecord in_rec) {
100  F_ENTRY;
101  if ( solver == NULL ) xprintf(PrgErr,"Structure solver not allocated.\n");
102 
103  if (in_rec.type() == Solver::input_type_petsc ) {
104  solver->type = PETSC_SOLVER;
105  solver->params = Input::Record(in_rec).val<string>("options");
106  } else
107  if (in_rec.type() == Solver::input_type_bddc ) {
108  solver->type = PETSC_MATIS_SOLVER;
109  } else {
110  xprintf(UsrErr,"Unsupported solver: %s\n", in_rec.type().type_name().c_str());
111  }
112 
113  solver->r_tol = Input::Record(in_rec).val<double>("r_tol");
114  solver->a_tol = Input::Record(in_rec).val<double>("a_tol");
115 
116 /* solver->executable = OptGetStr( "Solver", "Solver_executable",solver->name);
117 
118  solver->keep_files = OptGetBool( "Solver", "Keep_solver_files", "no" );
119  solver->manual_run = OptGetBool( "Solver", "Manual_solver_run", "no" );
120  solver->use_ctrl_file = OptGetBool( "Solver", "Use_control_file", "no" );
121  if (solver->use_ctrl_file)
122  solver->ctrl_file = IONameHandler::get_instance()->get_input_file_name(OptGetStr( "Solver", "Control_file", NULL )).c_str();
123  solver->use_last_sol =OptGetBool( "Solver", "Use_last_solution", "no" );
124  /// Last solution reuse is possible only for external solvers
125  if (solver->use_last_sol && (solver->type == PETSC_SOLVER)) {
126  xprintf(UsrErr,"Can not reuse last solution, when using an internal solver.");
127  }
128 
129  //! generic solver parameters
130  double solver_accuracy= OptGetDbl("Solver","Solver_accuracy","1.0e-7");
131  solver->max_it= OptGetInt("Solver", "max_it", "200" );
132  solver->r_tol= OptGetDbl("Solver", "r_tol", "-1" );
133  if (solver->r_tol < 0) solver->r_tol=solver_accuracy;
134  solver->a_tol= OptGetDbl("Solver", "a_tol", "1.0e-9" );
135 
136  if (solver->type == ISOL) {
137  solver->isol_params=(ISOL_params *)malloc(sizeof(ISOL_params));
138  isol_params_init(solver->isol_params);
139  }*/
140 }
141 
142 
143 
144 
145 //=============================================================================
146 /*! @brief Set solver type from its name.
147  *
148  * The name comparison is case insensitive.
149  */
150 /// one test macro
151 #define TEST_TYPE(name_str,id) if ( strcmpi( solver->name, name_str ) == 0 ) solver->type = (id);
152 
153 void solver_set_type( Solver *solver )
154 {
155  F_ENTRY;
156  solver->type=UNKNOWN;
157  TEST_TYPE("petsc",PETSC_SOLVER);
158  //TEST_TYPE("petsc_matis",PETSC_MATIS_SOLVER);
159  TEST_TYPE("bddcml",BDDCML_SOLVER);
160  TEST_TYPE("si2",SI2);
161  TEST_TYPE("gi8",GI8);
162  TEST_TYPE("isol",ISOL);
163  TEST_TYPE("matlab",MATLAB);
164 
165 }
166 
167 //=============================================================================
168 /*! @brief Solves a given linear system.
169  *
170  * Call user selected internal or external solver.
171  * @param[in] solver solver structure to use
172  * @param[in,out] system linear system to solve, conatains also result
173  *
174  * @pre Initialized solver. Assembled system.
175  * @post Valid solution.
176  */
177 
178 void solve_system( struct Solver *solver, struct LinSys *system )
179 {
180 START_TIMER("solve_system");
181 /// set command line for external solvers
182 #define SET_GENERIC_CALL sprintf( cmdline, "%s %s",solver->executable,solver->params.c_str())
183 #define SET_MATLAB_CALL sprintf( cmdline, "matlab -r solve" )
184 
185  char cmdline[ 1024 ];
186 
187  ASSERT( NONULL( solver ),"NULL 'solver' argument.\n");
188  ASSERT( NONULL( system ),"NULL 'system' argument.\n");
189 
190  solver->LinSys=system;
191  switch (solver->type) {
192  // internal solvers
193  case PETSC_SOLVER:
194  case PETSC_MATIS_SOLVER:
195 // solver_petsc( solver );
196  break;
197  // external solvers
198  case ISOL:
200  RunExtern(solver,cmdline,&write_sys_isol, &read_sol_matlab);
201  case MATLAB:
203  RunExtern(solver,cmdline,&write_sys_matlab,&read_sol_matlab);
204  break;
205  case GI8:
206  case SI2:
207  xprintf(UsrErr,"Solver %s is not supported.\n",solver->name);
208  case UNKNOWN:
209  xprintf(UsrErr,"UNKNOWN solver is not supported.\n");
210  }
211 
212 }
213 
214 //=============================================================================
215 /*! @brief Call an external solver.
216  *
217  * Make temporary directory, write down matrix and RHS vector. Then
218  * perform system call of given program and read solution form given file.
219  *
220  * @param[in,out] solver solver structure to use (solution in linear system)
221  * @param[in] cmdline calling command line
222  * @param[in] write_sys function to write down linear system
223  * @param[in] read_sol function to read the solution
224  */
225 
226 
227 void RunExtern( Solver *solver,char *cmdline,
228  void (*write_sys)(Solver *), void (*read_sol)(Solver *) )
229 {
230  char cmd[ LINE_SIZE ];
231 
232  xmkdir( "tmp" );
233  xchdir( "tmp" );
234  // TODO: use_last_sol by melo mit parametr s odkazem kde jsou data
235  // a jakeho typu, malo by jit ulozit i z vnitrniho solveru
236  if (! solver->use_last_sol) {
237  /// prepare data
238  clean_directory();
239  xprintf( Msg, "Writing files for solver... ")/*orig verb 2*/;
240  (*write_sys)(solver); // prepare solver specific input files
241  xprintf(Msg, "run extr. solver\n");
242  /// if user provides an explicit control file, use that one instead
243  if( solver->use_ctrl_file == true ) {
244  sprintf( cmd, "copy /Y ../%s ", solver->ctrl_file );
245  xsystem( cmd );
246  }
247 
248  /// run the solver
249  if( solver->manual_run == true ) {
250  xprintf( Msg, "\nPROGRAM PAUSED.\n"
251  "Start solver of linear equations manually:\n\n%s\n\n"
252  "Press ENTER when calculation finished.\n" );
253  getchar();
254  } else {
255  xprintf( Msg, "\nCalling solver... \n"
256  "BEGIN OF SOLVER'S MESSAGES\n");
257  strcpy(cmd,cmdline);
258  // pipe stdout and stderr through tee to get it to both, the screen and the logfile
259  strcat(cmd," 2>&1 | tee ../flow_extern_solver.log");
260  xsystem( cmd );
261  }
262  }
263  /// read the solution
264  (*read_sol)( solver );
265 
266  if( solver->keep_files == false ) {
267  clean_directory();
268  xchdir( ".." );
269  xremove( "tmp" );
270  } else {
271  xchdir( ".." );
272  }
273 
274  xprintf( Msg, "END OF MESSAGES OF THE SOLVER\n\n");
275 }
276 //=============================================================================
277 /*! @brief Clean temporary directory of external solver.
278  */
279 
280 void clean_directory( void )
281 {
282  xremove( "rid.ghp" );
283  xremove( "vector.sro" );
284  xremove( "vector.sri" );
285  xremove( "vector.log" );
286  xremove( "solve.m" );
287  xremove( "matrix.dat" );
288  xremove( "rhs.dat" );
289  xremove( "solution.dat" );
290 }
291 
292 //=========================================================================
293 /*! @brief solve given system by internal PETSC KSP solver.
294  *
295  * - insert given or default option string into the PETSc options db
296  * - create KSP
297  * - set tolerances
298  * - solve, report number of iterations and convergency reason
299  *
300  * default choice of PETSC solver options:
301  *
302  * - for SPD system (using NSchurs=1,2):\n
303  * "-ksp_type cg -pc_type ilu -pc_factor_levels 5 -ksp_diagonal_scale_fix"\n
304  * (CG solver and ILU preconditioner with 5 levels and diagonal scaling)
305  * - for other system (NSchurs=0):\n
306  * "-ksp_type bcgs -pc_type ilu -pc_factor_levels 5 -ksp_diagonal_scale fix"\n
307  * (BiCGStab solver and ILU preconditioner with 5 levels and diagonal scaling)\n
308  *
309  * For bad systems you can try:
310  * - remove diagonal scaling
311  * - use additional option: "-pc_factor_shift_nonzero"
312  *
313  * To this end you can use either the command line or <b> [Solver] petsc_options </b> parameter.
314  *
315  *
316  * @}
317  */
318 
319 void solver_petsc(Solver *solver)
320 {
321  LinSys *sys=solver->LinSys;
322  KSP System;
323  KSPConvergedReason Reason;
324  //PetscViewer mat_view;
325  const char *petsc_dflt_opt;
326  const char *petsc_str;
327  int nits;
328 
329  F_ENTRY;
330 
331  //LSView(sys);
332 
333  int np;
335 
336  if (solver->type == PETSC_MATIS_SOLVER) {
337  if (np > 1) {
338 
339  // parallel setting
340  if (sys->is_positive_definite())
341  petsc_dflt_opt="-ksp_type cg -pc_type nn -nn_coarse_pc_factor_mat_solver_package mumps -is_localD_pc_factor_mat_solver_package mumps -is_localN_pc_factor_mat_solver_package mumps";
342  else
343  if (sys->is_symmetric())
344  petsc_dflt_opt="-ksp_type minres -pc_type nn -nn_coarse_pc_factor_mat_solver_package mumps -is_localD_pc_factor_mat_solver_package mumps -is_localN_pc_factor_mat_solver_package mumps";
345  else
346  petsc_dflt_opt="-ksp_type bcgs -pc_type nn -nn_coarse_pc_factor_mat_solver_package mumps -is_localD_pc_factor_mat_solver_package mumps -is_localN_pc_factor_mat_solver_package mumps";
347 
348  } else {
349  // serial setting
350  if (sys->is_positive_definite())
351  petsc_dflt_opt="-ksp_type cg -pc_type nn -nn_coarse_pc_factor_mat_solver_package mumps -is_localD_pc_factor_mat_solver_package mumps -is_localN_pc_factor_mat_solver_package mumps";
352  else
353  if (sys->is_symmetric())
354  petsc_dflt_opt="-ksp_type minres -pc_type nn -nn_coarse_pc_factor_mat_solver_package mumps -is_localD_pc_factor_mat_solver_package mumps -is_localN_pc_factor_mat_solver_package mumps";
355  else
356  petsc_dflt_opt="-ksp_type bcgs -pc_type nn -nn_coarse_pc_factor_mat_solver_package mumps -is_localD_pc_factor_mat_solver_package mumps -is_localN_pc_factor_mat_solver_package mumps";
357  }
358  }
359  else
360  {
361  // -mat_no_inode ... inodes are usefull only for
362  // vector problems e.g. MH without Schur complement reduction
363  if (np > 1) {
364  // parallel setting
365  if (sys->is_positive_definite())
366  petsc_dflt_opt="-ksp_type bcgs -ksp_diagonal_scale_fix -pc_type asm -pc_asm_overlap 4 -sub_pc_type ilu -sub_pc_factor_levels 3 -sub_pc_factor_fill 6.0";
367  //petsc_dflt_opt="-ksp_type preonly -pc_type cholesky -pc_factor_mat_solver_package mumps -mat_mumps_sym 1";
368  // -ksp_type preonly -pc_type lu
369  else
370  petsc_dflt_opt="-ksp_type bcgs -ksp_diagonal_scale_fix -pc_type asm -pc_asm_overlap 4 -sub_pc_type ilu -sub_pc_factor_levels 3";
371 
372  } else {
373  // serial setting
374  if (sys->is_positive_definite())
375  //petsc_dflt_opt="-ksp_type bcgs -pc_type ilu -pc_factor_levels 3 -ksp_diagonal_scale_fix -pc_factor_fill 6.0";
376  petsc_dflt_opt="-ksp_type cg -pc_type ilu -pc_factor_levels 3 -ksp_diagonal_scale_fix -pc_factor_shift_positive_definite -pc_factor_fill 6.0";
377  else
378  petsc_dflt_opt="-ksp_type bcgs -pc_type ilu -pc_factor_levels 5 -ksp_diagonal_scale_fix";
379  }
380  }
381 
382  if (solver->params == "") petsc_str=petsc_dflt_opt;
383  else petsc_str=solver->params.c_str();
384  //OptGetStr("Solver","Solver_params",petsc_dflt_opt);
385 
386  xprintf(MsgVerb,"inserting petsc options: %s\n", petsc_str );
387 
388  PetscOptionsInsertString(petsc_str); // overwrites previous options values
389  //xfree(petsc_str);
390 
391  MatSetOption(sys->get_matrix(), MAT_USE_INODES, PETSC_FALSE);
392 
393 
394  // xprintf(Msg,"View KSP system\n");
395  //Mat matrixForPrint;
396  //PetscErrorCode ierr;
397  //PetscInt m, n;
398  //MatGetSize( sys->get_matrix(), &m, &n );
399 
400  //ierr = MatCreate( PETSC_COMM_WORLD, &matrixForPrint ); CHKERRV( ierr );
401  //ierr = MatSetType( matrixForPrint, MATMPIAIJ ); CHKERRV( ierr );
402  //ierr = MatSetSizes( matrixForPrint, PETSC_DECIDE, PETSC_DECIDE, m, n );
403 
404  //std::cout << "Size of the matrix is :" << m << ", " << n << std::endl;
405  //Vec auxIn, auxOut;
406  //for ( int i = 0; i < n; i++ ) {
407  // // create auxiliary vector of unit matrix
408  // ierr = MatGetVecs( sys->get_matrix(), &auxIn, &auxOut ); CHKERRV( ierr );
409 
410  // VecSetValue( auxIn, i, 1., INSERT_VALUES );
411  // ierr = VecAssemblyBegin( auxIn ); CHKERRV( ierr );
412  // ierr = VecAssemblyEnd( auxIn ); CHKERRV( ierr );
413 
414  // ierr = MatMult( sys->get_matrix(), auxIn, auxOut ); CHKERRV( ierr );
415 
416  // PetscInt low, high;
417  // VecGetOwnershipRange( auxOut, &low, &high );
418  // PetscInt locSize = high - low;
419 
420  // PetscScalar *values;
421  // VecGetArray( auxOut, &values );
422 
423  // std::vector<PetscInt> rows;
424  // std::vector<PetscInt> columns;
425  // for ( int j = low; j < high; j++ ) {
426  // rows.push_back( j );
427  // }
428  // columns.push_back( i );
429 
430  // MatSetValues( matrixForPrint, locSize, &(rows[0]), 1, &(columns[0]), values, INSERT_VALUES );
431 
432  // VecRestoreArray( auxOut, &values );
433  // VecDestroy( auxIn );
434  // VecDestroy( auxOut );
435  //}
436  //ierr = MatAssemblyBegin( matrixForPrint, MAT_FINAL_ASSEMBLY ); CHKERRV( ierr );
437  //ierr = MatAssemblyEnd( matrixForPrint, MAT_FINAL_ASSEMBLY ); CHKERRV( ierr );
438 
439 
440  //PetscViewer matViewer;
441  //PetscViewerASCIIOpen( PETSC_COMM_WORLD, "matrix.m", &matViewer );
442  //PetscViewerSetFormat(matViewer,PETSC_VIEWER_ASCII_MATLAB);
443  //MatView( matrixForPrint, matViewer );
444  //MatDestroy( matrixForPrint );
445  //PetscViewerDestroy(matViewer);
446 
447  //PetscViewer rhsViewer;
448  //PetscViewerASCIIOpen( PETSC_COMM_WORLD, "rhs.m", &rhsViewer );
449  //PetscViewerSetFormat(rhsViewer,PETSC_VIEWER_ASCII_MATLAB);
450  //VecView( sys->get_rhs(), rhsViewer );
451  //PetscViewerDestroy(rhsViewer);
452 
453  KSPCreate(PETSC_COMM_WORLD,&System);
454  KSPSetOperators(System, sys->get_matrix(), sys->get_matrix(), DIFFERENT_NONZERO_PATTERN);
455  KSPSetTolerances(System, solver->r_tol, solver->a_tol, PETSC_DEFAULT,PETSC_DEFAULT);
456  KSPSetFromOptions(System);
457 
458  START_TIMER("iteration-PETSC solver");
459  KSPSolve(System, sys->get_rhs(), sys->get_solution());
460  KSPGetConvergedReason(System,&Reason);
461  KSPGetIterationNumber(System,&nits);
462 
463  // TODO: make solver part of LinSyt, and make gatter for num of it
464  xprintf(Msg,"convergence reason %d, number of iterations is %d\n", Reason, nits);
465  ADD_CALLS(nits);
466  KSPDestroy(&System);
467  END_TIMER("iteration");
468 
469 }
470 
471 //=============================================================================
472 //=============================================================================
473 /// @brief ISOL calling functions
474 //!@{
475 
476 //=============================================================================
477 /* @brief Read ISOL specific parameters.
478  *
479  */
481 
482  F_ENTRY;
483  /*
484  par->method = OptGetStr( "Solver parameters", "method", "fgmres" );
485  par->restart = OptGetInt( "Solver parameters", "restart", "20");
486  par->stop_crit = OptGetStr( "Solver parameters", "stop_crit", "backerr" );
487  par->be_tol = OptGetDbl( "Solver parameters", "be_tol", "1e-10" );
488  par->stop_check = OptGetInt( "Solver parameters", "stop_check", "1" );
489  par->scaling = OptGetStr( "Solver parameters", "scaling", "mc29_30" );
490  par->precond = OptGetStr( "Solver parameters", "precond", "ilu" );
491  par->sor_omega = OptGetDbl( "Solver parameters", "sor_omega", "1.0" );
492  par->ilu_cpiv = OptGetInt( "Solver parameters", "ilu_cpiv", "0" );
493  par->ilu_droptol = OptGetDbl( "Solver parameters", "ilu_droptol", "1e-3" );
494  par->ilu_dskip = OptGetInt( "Solver parameters", "ilu_dskip", "-1" );
495  par->ilu_lfil = OptGetInt( "Solver parameters", "ilu_lfil", "-1" );
496  par->ilu_milu = OptGetInt( "Solver parameters", "ilu_milu", "0" );
497  */
498 }
499 
500 //=============================================================================
501 /*! @brief Write down input for ISOL
502  *
503  */
504 void write_sys_isol( struct Solver *solver )
505 {
506  FILE * fconf;
507  ISOL_params * par=solver->isol_params;
508 
509  F_ENTRY;
510  /// write the control file
511  fconf = xfopen( "isol.conf", "wt" );
512  xfprintf( fconf, "mat_file = matrix.dat\n" );
513  xfprintf( fconf, "mat_fmt = coo\n" );
514  xfprintf( fconf, "rhs_file = rhs.dat\n" );
515  xfprintf( fconf, "mat_sym = 1\n" );
516  xfprintf( fconf, "mat_id_off = 0\n" );
517  xfprintf( fconf, "mat_symmetrize = 1\n" );
518  xfprintf( fconf, "sol0_file = 0\n" );
519  xfprintf( fconf, "sol_file = solution.dat\n" );
520  DBGMSG("first\n");
521  xfprintf( fconf, "method = %s\n", par->method);
522  DBGMSG("second\n");
523  xfprintf( fconf, "max_it = %d\n",solver->max_it );
524  xfprintf( fconf, "max_dim = %d\n",par->restart );
525  xfprintf( fconf, "stop_crit = %s\n",par->stop_crit );
526  xfprintf( fconf, "rel_tol = %e\n",solver->r_tol );
527  xfprintf( fconf, "abs_tol = %e\n", solver->a_tol);
528  xfprintf( fconf, "be_tol = %e\n",par->be_tol );
529  xfprintf( fconf, "stop_check = %d\n",par->stop_check );
530  xfprintf( fconf, "scaling = %s\n",par->scaling );
531  xfprintf( fconf, "precond = %s\n",par->precond );
532  xfprintf( fconf, "sor_omega = %e\n",par->sor_omega );
533  xfprintf( fconf, "ilu_droptol = %e\n",par->ilu_droptol );
534  xfprintf( fconf, "ilu_milu = %d\n",par->ilu_milu );
535  xfprintf( fconf, "ilu_cpiv = %d ! do not use at the moment, needs some fixing!\n",
536  par->ilu_cpiv );
537  if(par->ilu_dskip == -1)
538  xprintf(PrgErr,"Sorry, ilu_dskip parameter is not supported.\n");
539 // par->ilu_dskip = solver->LinSys->sizeA;
540  xfprintf( fconf, "ilu_dskip = %d\n",par->ilu_dskip );
541  xfprintf( fconf, "ilu_lfil = %d\n",par->ilu_lfil);
542  xfclose( fconf );
543 
544  /// write the linear system - using MATLAB format
545  write_matlab_linsys(solver->LinSys,1);
546 }
547 //!@}
548 // ISOL block
549 
550 //void write_sys_gm6( Solver *solver )
551 //void write_vector_sro( LinSystem *mtx )
552 //void read_sol_gm6( Solver *solver )
553 //============================================================================
554 //============================================================================
555 /// @brief MATLAB call functions
556 //!@{
557 
558 //=============================================================================
559 /*! @brief Write input for MATLAB
560  *
561  * written files: matrix.dat, rhs.dat, solve.m
562  */
563 void write_sys_matlab( struct Solver *solver )
564 {
565  FILE *out;
566 
567  //solve.m
568  out = xfopen( "solve.m", "wt" );
569  xfprintf( out, "load matrix.dat\n" );
570  xfprintf( out, "a = spconvert( matrix )\n" );
571 // xfprintf( out, "a = a + tril( transpose( a ), -1 )\n" ); // be sure about symmetry
572  xfprintf( out, "load rhs.dat\n" );
573  xfprintf( out, "sol = a \\ rhs\n" );
574  xfprintf( out, "save solution.dat sol -ascii -double\n" );
575  xfprintf( out, "exit\n" );
576  xfclose( out );
577 
578  write_matlab_linsys(solver->LinSys,0);
579 }
580 
581 //==========================================================================
582 /*! @brief Write MATLAB system
583  *
584  * Write matrix in MATLAB format to matrix.dat and RHS into rhs.dat.
585  * @param[in] mtx Linear system to write out.
586  * @param[in] write_nz (1 - write number of non-zeroes (ISOL); 0 - don't write (MATLAB))
587  */
588 void write_matlab_linsys(LinSys *mtx,int write_nz) {
589  //FILE *out;
590  //int mi, ji,nnz;
591 
592  F_ENTRY;
593 
594  // use LinSys view to write down system in MATLAB format
595 /*
596  LSSetCSR( mtx );
597  if (write_nz) nnz=mtx->i[mtx->size];
598  else nnz=0;
599  /// matrix.dat
600  out = xfopen( "matrix.dat", "wt" );
601  xfprintf( out, "%d %d %d\n", mtx->size, mtx->size, nnz);
602  ji = 0;
603  for( mi = 1; mi <= mtx->size; mi++ )
604  for( ; ji < mtx->i[mi] ; ji++ )
605  xfprintf( out, "%d %d %.16lg\n",mi,mtx->j[ji] + 1, mtx->a[ ji ] );
606  xfclose( out );
607  /// rhs.dat
608  out = xfopen( "rhs.dat", "wt" );
609  for( mi = 0; mi < mtx->size; mi++ ) xfprintf( out, "%.16lg\n", mtx->vb[ mi ] );
610  xfclose( out );
611  */
612 }
613 
614 //=============================================================================
615 /*! @brief Read MATLAB solution into solver->LinSys->vx
616  */
617 void read_sol_matlab( struct Solver *solver )
618 {
619  LinSys *sys=solver->LinSys;
620  FILE *in;
621  double value;
622  unsigned int mi;
623 
624  in = xfopen( "solution.dat", "rt" );
625  int loc_row=0;
626  std::vector<double> solution(sys->size());
627  for( mi = 0; mi < sys->size(); mi++ )
628  {
629  xfscanf( in, "%lf", value );
630 
631  solution[mi] = value;
632 
633  }
634  xfclose( in );
635 
636  sys -> set_whole_solution( solution );
637 }
638 
639 //-----------------------------------------------------------------------------
640 // vim: set cindent: