Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
AlephTrilinos.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* AlephTrilinos.cc (C) 2000-2025 */
9/* */
10/* Implementation of Aleph using Trilinos/Epetra. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/aleph/AlephArcane.h"
15
16#include "Epetra_config.h"
17#include "Epetra_Vector.h"
18#include "Epetra_MpiComm.h"
19#include "Epetra_Map.h"
20#include "Epetra_CrsMatrix.h"
21#include "Epetra_LinearProblem.h"
22#include "AztecOO.h"
23#include "ml_MultiLevelPreconditioner.h"
24#include "Ifpack_IC.h"
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Arcane
30{
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35class AlephVectorTrilinos : public IAlephVector
36{
37 public:
38
39 AlephVectorTrilinos(ITraceMng* tm, AlephKernel* kernel, Integer index)
40 : IAlephVector(tm, kernel, index)
41 {
42 debug() << "\t\t[AlephVectorTrilinos::AlephVectorTrilinos] new SolverVectorTrilinos";
43#ifdef HAVE_MPI
44 m_trilinos_Comm = new Epetra_MpiComm(*(MPI_Comm*)(m_kernel->subParallelMng(m_index)->getMPICommunicator()));
45#else
46 m_trilinos_Comm = new Epetra_SerialComm();
47#endif // HAVE_MPI
48 }
49
50 ~AlephVectorTrilinos()
51 {
52 delete m_trilinos_vector;
53 delete m_trilinos_Comm;
54 }
55
56 public:
57
58 /******************************************************************************
59 * AlephVectorCreate
60 *****************************************************************************/
61 void AlephVectorCreate(void)
62 {
63 debug() << "\t\t[AlephVectorTrilinos::AlephVectorCreate] TRILINOS VectorCreate";
64 Integer jlower = -1;
65 Integer jupper = 0;
66 for (int iCpu = 0; iCpu < m_kernel->size(); ++iCpu) {
67 if (m_kernel->rank() != m_kernel->solverRanks(m_index)[iCpu])
68 continue;
69 if (jlower == -1)
70 jlower = m_kernel->topology()->gathered_nb_row(iCpu);
71 jupper = m_kernel->topology()->gathered_nb_row(iCpu + 1) - 1;
72 }
73 Integer size = jupper - jlower + 1;
74 debug() << "\t\t[AlephVectorTrilinos::AlephVectorCreate] jlower=" << jlower << ", jupper=" << jupper;
75 Epetra_Map trilinos_Map = Epetra_Map(m_kernel->topology()->nb_row_size(),
76 size,
77 0,
78 *m_trilinos_Comm);
79 m_trilinos_vector = new Epetra_Vector(trilinos_Map);
80 debug() << "\t\t[AlephVectorTrilinos::AlephVectorCreate] done";
81 }
82
83 /******************************************************************************
84 * AlephVectorSet
85 *****************************************************************************/
86 void AlephVectorSet(const double* bfr_val, const int* bfr_idx, Integer size)
87 {
88 debug() << "\t\t[AlephVectorTrilinos::AlephVectorSet]";
89 m_trilinos_vector->ReplaceGlobalValues(size, bfr_val, bfr_idx);
90 /*#warning DUMPING trilinos
91 for(int i=0; i<size;++i){
92 debug()<<"\t\t[AlephVectorTrilinos::AlephVectorSet] @["<<bfr_idx[i]<<"]="<<bfr_val[i];
93 }*/
94 }
95
96 int AlephVectorAssemble(void)
97 {
98 //m_trilinos_vector->FillComplete();
99 return 0;
100 }
101
102 /******************************************************************************
103 * AlephVectorGet
104 *****************************************************************************/
105 void AlephVectorGet(double* bfr_val, const int* bfr_idx, Integer size)
106 {
107 ARCANE_UNUSED(bfr_idx);
108 debug() << "\t\t[AlephVectorTrilinos::AlephVectorGet]";
109 for (int i = 0; i < size; ++i) {
110 // bfr_val[i]=(*m_trilinos_vector)[bfr_idx[i]];
111 bfr_val[i] = (*m_trilinos_vector)[i];
112 /*#warning DUMPING trilinos
113 debug()<<"\t\t[AlephVectorTrilinos::AlephVectorGet] @["<<i<<"]="<<bfr_val[i];
114*/
115 }
116 }
117
118 /******************************************************************************
119 * writeToFile
120 *****************************************************************************/
121 void writeToFile(const String filename)
122 {
123 ARCANE_UNUSED(filename);
124 debug() << "\t\t[AlephVectorTrilinos::writeToFile]";
125 }
126
127 /******************************************************************************
128 * LinftyNorm
129 * int NormInf (double * Result) const;
130 *****************************************************************************/
131 Real LinftyNorm(void)
132 {
133 Real Result;
134 if (m_trilinos_vector->NormInf(&Result) != 0)
135 throw Exception("LinftyNorm", "NormInf error");
136 return Result;
137 }
138
139 /******************************************************************************
140 * LinftyNorm
141 *****************************************************************************/
142 void fill(Real value)
143 {
144 m_trilinos_vector->PutScalar(value);
145 }
146
147 public:
148
149 Epetra_Vector* m_trilinos_vector = nullptr;
150 Epetra_Comm* m_trilinos_Comm = nullptr;
151};
152
153/*---------------------------------------------------------------------------*/
154/*---------------------------------------------------------------------------*/
155
156/*---------------------------------------------------------------------------*/
157/*---------------------------------------------------------------------------*/
158
159class AlephMatrixTrilinos
160: public IAlephMatrix
161{
162 public:
163
164 /******************************************************************************
165 AlephMatrixTrilinos
166 *****************************************************************************/
167 AlephMatrixTrilinos(ITraceMng* tm, AlephKernel* kernel, Integer index)
168 : IAlephMatrix(tm, kernel, index)
169 {
170 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixTrilinos] new AlephMatrixTrilinos";
171#ifdef HAVE_MPI
172 m_trilinos_Comm = new Epetra_MpiComm(*(MPI_Comm*)(m_kernel->subParallelMng(m_index)->getMPICommunicator()));
173#else
174 m_trilinos_Comm = new Epetra_SerialComm();
175#endif // HAVE_MPI
176 }
177
178 ~AlephMatrixTrilinos()
179 {
180 delete m_trilinos_matrix;
181 delete m_trilinos_Comm;
182 }
183
184 /******************************************************************************
185 * AlephMatrixCreate
186 *****************************************************************************/
187 void AlephMatrixCreate(void)
188 {
189 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixCreate] TRILINOS MatrixCreate idx:" << m_index;
190 Integer ilower = -1;
191 Integer iupper = 0;
192 for (int iCpu = 0; iCpu < m_kernel->size(); ++iCpu) {
193 if (m_kernel->rank() != m_kernel->solverRanks(m_index)[iCpu])
194 continue;
195 if (ilower == -1)
196 ilower = m_kernel->topology()->gathered_nb_row(iCpu);
197 iupper = m_kernel->topology()->gathered_nb_row(iCpu + 1) - 1;
198 }
199 Integer size = iupper - ilower + 1;
200
201 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixCreate] ilower=" << ilower << ", iupper=" << iupper;
202 Integer jlower = ilower;
203 Integer jupper = iupper;
204
205 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixCreate] jlower=" << jlower << ", jupper=" << jupper;
206 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixCreate] global=" << m_kernel->topology()->nb_row_size();
207 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixCreate] size=" << size;
208
209 Epetra_Map trilinos_Map = Epetra_Map(m_kernel->topology()->nb_row_size(),
210 size,
211 0,
212 *m_trilinos_Comm);
213 m_trilinos_matrix = new Epetra_CrsMatrix(Copy,
214 trilinos_Map,
215 m_kernel->topology()->gathered_nb_row_elements().subView(ilower, size).unguardedBasePointer(),
216 false);
217 }
218
219 /******************************************************************************
220 * AlephMatrixSetFilled
221 *****************************************************************************/
222 void AlephMatrixSetFilled(bool) {}
223
224 /******************************************************************************
225 * AlephMatrixConfigure
226 *****************************************************************************/
227 int AlephMatrixAssemble(void)
228 {
229 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixAssemble] AlephMatrixAssemble";
230 m_trilinos_matrix->FillComplete();
231 return true;
232 }
233
234 /******************************************************************************
235 * AlephMatrixFill
236 *****************************************************************************/
237 void AlephMatrixFill(int size, int* rows, int* cols, double* values)
238 {
239 [[maybe_unused]] int rtn = 0;
240 for (int i = 0; i < size; i++) {
241 // int InsertGlobalValues(int GlobalRow, int NumEntries, double* Values, int* Indices);
242 /*#warning TRILINOS DUMP
243 debug()<<"\t\t[AlephMatrixTrilinos::AlephMatrixFill] A["<<rows[i]<<"]["<<cols[i]<<"]="<<values[i];
244*/
245 rtn += m_trilinos_matrix->InsertGlobalValues(rows[i], 1, &values[i], &cols[i]);
246 }
247
248 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixFill] done";
249 }
250
251 /******************************************************************************
252 * LinftyNormVectorProductAndSub
253 *****************************************************************************/
254 Real LinftyNormVectorProductAndSub(AlephVector* x,
255 AlephVector* b)
256 {
257 ARCANE_UNUSED(x);
258 ARCANE_UNUSED(b);
259 throw FatalErrorException("LinftyNormVectorProductAndSub", "error");
260 }
261
262 /******************************************************************************
263 * isAlreadySolved
264 *****************************************************************************/
265 bool isAlreadySolved(AlephVectorTrilinos* x,
268 Real* residual_norm,
269 AlephParams* params)
270 {
271 const bool convergence_analyse = true; //params->convergenceAnalyse();
272
273 // test the right-hand side of the linear system
274 const Real res0 = b->LinftyNorm();
275
276 if (convergence_analyse)
277 debug() << "convergence analysis: max norm of the right-hand side res0: " << res0;
278
279 const Real considered_as_null = params->minRHSNorm();
280 if (res0 < considered_as_null) {
281 x->fill(Real(0.0));
282 residual_norm[0] = res0;
283 if (convergence_analyse)
284 debug() << "convergence analysis: the right-hand side of the linear system is less than: " << considered_as_null;
285 return true;
286 }
287
288 if (params->xoUser()) {
289 // we test if b is already a solution to the system within epsilon
290 //matrix->vectorProduct(b, tmp_vector); tmp_vector->sub(x);
291 m_trilinos_matrix->Multiply(false,
292 *x->m_trilinos_vector,
293 *tmp->m_trilinos_vector); // tmp=A*x
294 tmp->m_trilinos_vector->Update(-1.0,
295 *b->m_trilinos_vector,
296 1.0); // tmp=A*x-b
297 const Real residu = tmp->LinftyNorm();
298 //debug() << "[IAlephTrilinos::isAlreadySolved] residual="<<residu;
299
300 if (residu < considered_as_null) {
301 if (convergence_analyse) {
302 debug() << "convergence analysis: |Ax0-b| is less than " << considered_as_null;
303 debug() << "convergence analysis: x0 is already a solution to the system.";
304 }
305 residual_norm[0] = residu;
306 return true;
307 }
308
309 const Real relative_error = residu / res0;
310 if (convergence_analyse)
311 debug() << "convergence analysis: initial residual : " << residu
312 << " --- initial relative residual (residu/res0) : " << residu / res0;
313
314 if (relative_error < (params->epsilon())) {
315 if (convergence_analyse)
316 debug() << "convergence analysis: X is already a solution to the system";
317 residual_norm[0] = residu;
318 return true;
319 }
320 }
321 if (convergence_analyse)
322 debug() << "convergence analysis: return false";
323 return false;
324 }
325
326 /******************************************************************************
327 * AlephMatrixSolve
328 *****************************************************************************/
329 int AlephMatrixSolve(AlephVector* x,
330 AlephVector* b,
331 AlephVector* t,
332 Integer& nb_iteration,
333 Real* residual_norm,
334 AlephParams* solver_param)
335 {
336 Ifpack_IC* ICPrecond = nullptr;
337 Teuchos::ParameterList* MLList = nullptr;
338 ML_Epetra::MultiLevelPreconditioner* MLPrecond = nullptr;
339 const String func_name("SolverMatrixTrilinos::solve");
340
341 AlephVectorTrilinos* x_tri = dynamic_cast<AlephVectorTrilinos*>(x->implementation());
342 AlephVectorTrilinos* b_tri = dynamic_cast<AlephVectorTrilinos*>(b->implementation());
343 AlephVectorTrilinos* t_tri = dynamic_cast<AlephVectorTrilinos*>(t->implementation());
344
348
349 if (isAlreadySolved(x_tri, b_tri, t_tri, residual_norm, solver_param)) {
350 ItacRegion(isAlreadySolved, AlephMatrixSloop);
351 debug() << "\t[AlephMatrixSloop::AlephMatrixSolve] isAlreadySolved !";
352 nb_iteration = 0;
353 return 0;
354 }
355
356 Epetra_Vector* X = x_tri->m_trilinos_vector;
357 Epetra_Vector* B = b_tri->m_trilinos_vector;
358
359 if (!solver_param->xoUser())
360 x_tri->fill(0.0);
361
362 // Create Linear Problem
363 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixSolve] Create Linear Problem";
364 Epetra_LinearProblem problem(m_trilinos_matrix, X, B);
365
366 // Create AztecOO instance
367 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixSolve] Create AztecOO instance";
368 AztecOO solver(problem);
369 // Options can be: AZ_none AZ_last AZ_summary AZ_warnings
370 solver.SetAztecOption(AZ_output, solver_param->getOutputLevel());
371
372 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixSolve] Setting options";
373 switch (solver_param->method()) {
374 case TypesSolver::PCG:
375 solver.SetAztecOption(AZ_solver, AZ_cg);
376 break;
377 case TypesSolver::BiCGStab:
378 solver.SetAztecOption(AZ_solver, AZ_bicgstab);
379 break;
380 case TypesSolver::BiCGStab2:
381 solver.SetAztecOption(AZ_solver, AZ_bicgstab);
382 break;
383 case TypesSolver::GMRES:
384 solver.SetAztecOption(AZ_solver, AZ_gmres);
385 break;
386 case TypesSolver::SuperLU:
387 solver.SetAztecOption(AZ_solver, AZ_slu);
388 break;
389 default:
390 throw ArgumentException(func_name, "unknown solver");
391 }
392
393 switch (solver_param->precond()) {
394 case TypesSolver::NONE:
395 solver.SetAztecOption(AZ_precond, AZ_none);
396 break;
397 case TypesSolver::DIAGONAL:
398 solver.SetAztecOption(AZ_precond, AZ_Jacobi);
399 break;
400 case TypesSolver::ILU: {
401 solver.SetAztecOption(AZ_precond, AZ_dom_decomp);
402 solver.SetAztecOption(AZ_subdomain_solve, AZ_ilu);
403 break;
404 }
405 case TypesSolver::ILUp:
406 solver.SetAztecOption(AZ_precond, AZ_bilu);
407 break;
408 case TypesSolver::POLY:
409 solver.SetAztecOption(AZ_precond, AZ_Neumann);
410 break;
411 case TypesSolver::AMG: { // Taken from trilinos-x.y.z-Source/packages/ml/examples/BasicExamples/*
412 MLList = new Teuchos::ParameterList();
413 /* Setting parameter for aggregation-based preconditioners:
414 - "SA" : classical smoothed aggregation preconditioners;
415 - "NSSA" : default values for Petrov-Galerkin preconditioner for nonsymmetric systems
416 - "maxwell" : default values for aggregation preconditioner for eddy current systems
417 - "DD" : defaults for 2-level domain decomposition preconditioners based on aggregation;
418 - "DD-LU" : Like "DD", but use exact LU decompositions on each subdomain;
419 - "DD-ML" : 3-level domain decomposition preconditioners, with coarser spaces defined by aggregation;
420 - "DD-ML-LU" : Like "DD-ML", but with LU decompositions on each subdomain.
421 */
422 ML_Epetra::SetDefaults("SA", *MLList);
423 //MLList->set("ML output", 10); // output level, 0 being silent and 10 verbose
424 //MLList->set("max levels",16); // maximum number of levels
425 //MLList->set("increasing or decreasing","increasing"); // set finest level to 0
426 MLList->set("cycle applications", solver_param->getAmgSolverIter());
427 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixSolve] Setting cycle application=" << solver_param->getAmgSolverIter();
428 //MLList->set("aggregation: type", "MIS"); // use MIS scheme to create the aggregate
429 //MLList->set("smoother: type","Chebyshev"); // smoother is Chebyshev
430 MLList->set("smoother: sweeps", solver_param->getAmgSmootherIter());
431 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixSolve] Setting smoother: sweeps=" << solver_param->getAmgSmootherIter();
432 //MLList->set("smoother: pre or post", "both"); // use both pre and post smoothing
433 //MLList->set("coarse: type","Amesos-KLU"); // solve with serial direct solver KLU
434 //MLList->set("coarse: max size",32); // maximum allowed coarse size
435 MLList->set("ML debug mode", false);
436
437 MLPrecond = new ML_Epetra::MultiLevelPreconditioner(*m_trilinos_matrix, *MLList);
438 //MLPrecond->PrintUnused(0); // verify unused parameters on process 0 (put -1 to print on all processes)
439 //MLPrecond->AnalyzeHierarchy(true,1,1,1);
440 // MLPrec->ReComputePreconditioner(); // Cheap recompute the preconditioner
441 // It is supposed that the linear system matrix has different values, but
442 // **exactly** the same structure and layout. The code re-built the
443 // hierarchy and re-setup the smoothers and the coarse solver using
444 // already available information on the hierarchy. A particular
445 // care is required to use ReComputePreconditioner() with nonzero threshold.
446 // tell AztecOO to use the ML preconditioner
447 solver.SetPrecOperator(MLPrecond);
448 break;
449 }
450 case TypesSolver::IC: {
451 ICPrecond = new Ifpack_IC(m_trilinos_matrix);
452 IFPACK_CHK_ERR(ICPrecond->Compute());
453 solver.SetPrecOperator(ICPrecond);
454 break;
455 }
456 case TypesSolver::SPAIstat:
457 throw ArgumentException(func_name, "AztecOO::SPAIstat preconditioner unavailable");
458 case TypesSolver::AINV:
459 throw ArgumentException(func_name, "AztecOO::AINV preconditioner unavailable");
460 case TypesSolver::SPAIdyn:
461 throw ArgumentException(func_name, "AztecOO::SPAIdyn preconditioner unavailable");
462 default:
463 throw ArgumentException(func_name, "unknown preconditioner");
464 }
465
466 // Solver triggering
467 // Iterates on the current problem until MaxIters or Tolerance is reached.
468 solver.Iterate(solver_param->maxIter(), solver_param->epsilon());
469
470 double norm[1];
471 solver.GetLHS()->Norm2(norm);
472 double real_residual;
473 X->Norm2(&real_residual);
474
475 debug() << "[AlephMatrixTrilinos::AlephMatrixSolve]"
476 // Returns the total number of iterations performed on this problem
477 << "\n\t\tNumIters=" << solver.NumIters()
478 // Returns the true unscaled residual for this problem
479 << "\n\t\tTrueResidual=" << solver.TrueResidual()
480 // Returns the true scaled residual for this problem
481 << "\n\t\tScaledResidual=" << solver.ScaledResidual()
482 // Returns the recursive residual for this problem
483 << "\n\t\tRecursiveResidual=" << solver.RecursiveResidual()
484 << "\n\t\tnorm=" << norm[0]
485 << "\n\t\tRealResidual=" << real_residual;
486
487 nb_iteration = static_cast<Integer>(solver.NumIters());
488 residual_norm[0] = static_cast<Real>(solver.TrueResidual()); // vs ScaledResidual ?
489
490 if (solver_param->maxIter() <= nb_iteration)
491 throw Exception("Maximum number of solver iterations reached!",
492 "AlephMatrixTrilinos::AlephMatrixSolve");
493 /*if (solver_param->epsilon()<residual_norm[0])
494 throw Exception("Convergence not reached!", "AlephMatrixTrilinos::AlephMatrixSolve");
495 */
496
497 if (MLList != NULL)
498 delete MLList;
499 if (MLPrecond != NULL)
500 delete MLPrecond;
501 if (ICPrecond != NULL)
502 delete ICPrecond;
503
504 debug() << "\t\t[AlephMatrixTrilinos::AlephMatrixSolve] done";
505 return nb_iteration;
506 }
507
508 /******************************************************************************
509 * writeToFile
510 *****************************************************************************/
511 void writeToFile(const String filename)
512 {
513 ARCANE_UNUSED(filename);
514 }
515
516 private:
517
518 Epetra_CrsMatrix* m_trilinos_matrix = nullptr;
519 Epetra_Comm* m_trilinos_Comm = nullptr;
520};
521
522/*---------------------------------------------------------------------------*/
523/*---------------------------------------------------------------------------*/
524
525class TrilinosAlephFactoryImpl : public AbstractService
526, public IAlephFactoryImpl
527{
528 public:
529
530 TrilinosAlephFactoryImpl(const ServiceBuildInfo& sbi)
531 : AbstractService(sbi)
532 , m_IAlephVectors(0)
533 , m_IAlephMatrixs(0)
534 {}
535 ~TrilinosAlephFactoryImpl()
536 {
537 for (auto* v : m_IAlephVectors)
538 delete v;
539 for (auto* v : m_IAlephMatrixs)
540 delete v;
541 }
542
543 public:
544
545 virtual void initialize() {}
546 virtual IAlephTopology* createTopology(ITraceMng* tm,
547 AlephKernel* kernel,
548 Integer index,
549 Integer nb_row_size)
550 {
551 ARCANE_UNUSED(tm);
552 ARCANE_UNUSED(kernel);
553 ARCANE_UNUSED(index);
554 ARCANE_UNUSED(nb_row_size);
555 return nullptr;
556 }
557 virtual IAlephVector* createVector(ITraceMng* tm,
558 AlephKernel* kernel,
559 Integer index)
560 {
561 IAlephVector* new_vector = new AlephVectorTrilinos(tm, kernel, index);
562 m_IAlephVectors.add(new_vector);
563 return new_vector;
564 }
565
566 virtual IAlephMatrix* createMatrix(ITraceMng* tm,
567 AlephKernel* kernel,
568 Integer index)
569 {
570 IAlephMatrix* new_matrix = new AlephMatrixTrilinos(tm, kernel, index);
571 m_IAlephMatrixs.add(new_matrix);
572 return new_matrix;
573 }
574
575 private:
576
577 UniqueArray<IAlephVector*> m_IAlephVectors;
578 UniqueArray<IAlephMatrix*> m_IAlephMatrixs;
579};
580
581/*---------------------------------------------------------------------------*/
582/*---------------------------------------------------------------------------*/
583
585
586/*---------------------------------------------------------------------------*/
587/*---------------------------------------------------------------------------*/
588
589} // End namespace Arcane
590
591/*---------------------------------------------------------------------------*/
592/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_REGISTER_APPLICATION_FACTORY(aclass, ainterface, aname)
Registers a factory service for the class aclass.
AbstractService(const ServiceBuildInfo &)
Constructor from a ServiceBuildInfo.
Parameters of a linear system.
Definition AlephParams.h:32
Vector of a linear system.
Definition AlephVector.h:33
Interface of an implementation factory for Aleph.
Structure containing the information to create a service.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
1D data vector with value semantics (STL style).
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
double Real
Type representing a real number.