28 #include "libmesh/numeric_vector.h" 29 #include "libmesh/system.h" 30 #include "libmesh/petsc_matrix.h" 31 #include "libmesh/petsc_vector.h" 32 #include "libmesh/libmesh_common.h" 33 #include "libmesh/dof_map.h" 74 if (sys.have_vector(nm))
75 sys.remove_vector(nm);
80 if (sys.have_vector(nm))
81 sys.remove_vector(nm);
87 if (sys.have_vector(nm))
88 sys.remove_vector(nm);
93 if (sys.have_vector(nm))
94 sys.remove_vector(nm);
102 libMesh::NumericVector<Real>&
115 if (!sys.have_vector(nm))
118 return sys.get_vector(nm);
123 const libMesh::NumericVector<Real>&
136 if (!sys.have_vector(nm))
139 return sys.get_vector(nm);
143 libMesh::NumericVector<Real>&
156 if (!sys.have_vector(nm))
159 return sys.get_vector(nm);
163 const libMesh::NumericVector<Real>&
176 if (!sys.have_vector(nm))
179 return sys.get_vector(nm);
191 START_LOG(
"complex_solve()",
"PetscFieldSplitSolver");
200 Vec res, sol, res_vec_R, res_vec_I, sol_vec_R, sol_vec_I;
201 std::vector<IS> is(2);
202 std::vector<Mat> sub_mats(4);
203 sub_mats[0] =
dynamic_cast<libMesh::PetscMatrix<Real>*
>(sys.matrix)->mat();
204 sub_mats[1] =
dynamic_cast<libMesh::PetscMatrix<Real>*
>(sys.
matrix_A)->mat();
205 sub_mats[2] =
dynamic_cast<libMesh::PetscMatrix<Real>*
>(sys.
matrix_B)->mat();
206 sub_mats[3] =
dynamic_cast<libMesh::PetscMatrix<Real>*
>(sys.matrix)->mat();
213 CHKERRABORT(sys.comm().get(), ierr);
217 ierr = MatNestGetISs(mat, &is[0],
nullptr); CHKERRABORT(sys.comm().get(), ierr);
222 ierr = VecCreate(sys.comm().get(), &res); CHKERRABORT(sys.comm().get(), ierr);
223 ierr = VecSetSizes(res, PETSC_DECIDE, 2*sys.solution->size()); CHKERRABORT(sys.comm().get(), ierr);
224 ierr = VecSetType(res, VECMPI); CHKERRABORT(sys.comm().get(), ierr);
228 ierr = VecDuplicate(res, &sol); CHKERRABORT(sys.comm().get(), ierr);
233 ierr = VecGetSubVector(res, is[0], &res_vec_R); CHKERRABORT(sys.comm().get(), ierr);
234 ierr = VecGetSubVector(res, is[1], &res_vec_I); CHKERRABORT(sys.comm().get(), ierr);
237 ierr = VecGetSubVector(sol, is[0], &sol_vec_R); CHKERRABORT(sys.comm().get(), ierr);
238 ierr = VecGetSubVector(sol, is[1], &sol_vec_I); CHKERRABORT(sys.comm().get(), ierr);
242 std::unique_ptr<libMesh::NumericVector<Real> >
243 res_R(
new libMesh::PetscVector<Real>(res_vec_R, sys.comm())),
244 res_I(
new libMesh::PetscVector<Real>(res_vec_I, sys.comm())),
245 sol_R(
new libMesh::PetscVector<Real>(sol_vec_R, sys.comm())),
246 sol_I(
new libMesh::PetscVector<Real>(sol_vec_I, sys.comm()));
271 ierr = MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY); CHKERRABORT(sys.comm().get(), ierr);
272 ierr = MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY); CHKERRABORT(sys.comm().get(), ierr);
273 ierr = VecAssemblyBegin(res); CHKERRABORT(sys.comm().get(), ierr);
274 ierr = VecAssemblyEnd(res); CHKERRABORT(sys.comm().get(), ierr);
283 ierr = KSPCreate(sys.comm().get(), &ksp); CHKERRABORT(sys.comm().get(), ierr);
284 ierr = KSPSetOperators(ksp, mat, mat); CHKERRABORT(sys.comm().get(), ierr);
285 ierr = KSPSetFromOptions(ksp); CHKERRABORT(sys.comm().get(), ierr);
288 ierr = KSPGetPC(ksp, &pc); CHKERRABORT(sys.comm().get(), ierr);
289 ierr = PCFieldSplitSetIS(pc,
nullptr, is[0]);CHKERRABORT(sys.comm().get(), ierr);
290 ierr = PCFieldSplitSetIS(pc,
nullptr, is[1]);CHKERRABORT(sys.comm().get(), ierr);
291 ierr = PCSetFromOptions(pc); CHKERRABORT(sys.comm().get(), ierr);
296 ierr = KSPSolve(ksp, res, sol);
315 ierr = VecRestoreSubVector(res, is[0], &res_vec_R); CHKERRABORT(sys.comm().get(), ierr);
316 ierr = VecRestoreSubVector(res, is[1], &res_vec_I); CHKERRABORT(sys.comm().get(), ierr);
317 ierr = VecRestoreSubVector(sol, is[0], &sol_vec_R); CHKERRABORT(sys.comm().get(), ierr);
318 ierr = VecRestoreSubVector(sol, is[1], &sol_vec_I); CHKERRABORT(sys.comm().get(), ierr);
322 ierr = KSPDestroy(&ksp);
323 ierr = MatDestroy(&mat);
324 ierr = VecDestroy(&res);
325 ierr = VecDestroy(&sol);
327 STOP_LOG(
"complex_solve()",
"PetscFieldSplitSolver");
337 START_LOG(
"solve_block_matrix()",
"ComplexSolve");
343 libMesh::DofMap& dof_map = sys.get_dof_map();
346 my_m = dof_map.n_dofs(),
348 n_l = dof_map.n_dofs_on_processor(sys.processor_id()),
351 const std::vector<libMesh::dof_id_type>
352 & n_nz = dof_map.get_n_nz(),
353 & n_oz = dof_map.get_n_oz();
355 std::vector<libMesh::dof_id_type>
356 complex_n_nz (2*n_nz.size()),
357 complex_n_oz (2*n_oz.size());
360 for (
unsigned int i=0; i<n_nz.size(); i++) {
362 complex_n_nz[2*i] = 2*n_nz[i];
363 complex_n_nz[2*i+1] = 2*n_nz[i];
366 for (
unsigned int i=0; i<n_oz.size(); i++) {
368 complex_n_oz[2*i] = 2*n_oz[i];
369 complex_n_oz[2*i+1] = 2*n_oz[i];
378 ierr = MatCreate(sys.comm().get(), &mat); CHKERRABORT(sys.comm().get(), ierr);
379 ierr = MatSetSizes(mat, 2*m_l, 2*n_l, 2*my_m, 2*my_n); CHKERRABORT(sys.comm().get(), ierr);
381 if (libMesh::on_command_line(
"--solver_system_names")) {
384 MatSetOptionsPrefix(mat, nm.c_str());
386 ierr = MatSetFromOptions(mat); CHKERRABORT(sys.comm().get(), ierr);
389 ierr = MatSetBlockSize(mat, 2); CHKERRABORT(sys.comm().get(), ierr);
390 ierr = MatSeqAIJSetPreallocation(mat,
392 (PetscInt*)&complex_n_nz[0]); CHKERRABORT(sys.comm().get(), ierr);
393 ierr = MatMPIAIJSetPreallocation(mat,
395 (PetscInt*)&complex_n_nz[0],
397 (PetscInt*)&complex_n_oz[0]); CHKERRABORT(sys.comm().get(), ierr);
398 ierr = MatSeqBAIJSetPreallocation (mat, 2,
399 0, (PetscInt*)&n_nz[0]); CHKERRABORT(sys.comm().get(), ierr);
400 ierr = MatMPIBAIJSetPreallocation (mat, 2,
401 0, (PetscInt*)&n_nz[0],
402 0, (PetscInt*)&n_oz[0]); CHKERRABORT(sys.comm().get(), ierr);
403 ierr = MatSetOption(mat,
404 MAT_NEW_NONZERO_ALLOCATION_ERR,
405 PETSC_TRUE); CHKERRABORT(sys.comm().get(), ierr);
409 Vec res_vec, sol_vec;
411 ierr = MatCreateVecs(mat, &res_vec, PETSC_NULL); CHKERRABORT(sys.comm().get(), ierr);
412 ierr = MatCreateVecs(mat, &sol_vec, PETSC_NULL); CHKERRABORT(sys.comm().get(), ierr);
415 std::unique_ptr<libMesh::SparseMatrix<Real> >
416 jac_mat(
new libMesh::PetscMatrix<Real>(mat, sys.comm()));
418 std::unique_ptr<libMesh::NumericVector<Real> >
419 res(
new libMesh::PetscVector<Real>(res_vec, sys.comm())),
420 sol(
new libMesh::PetscVector<Real>(sol_vec, sys.comm()));
428 libMesh::NumericVector<Real>
433 first = sol_R.first_local_index(),
434 last = sol_I.last_local_index();
436 for (
unsigned int i=first; i<last; i++) {
438 sol->set( 2*i, sol_R(i));
439 sol->set(2*i+1, sol_I(i));
458 ierr = KSPCreate(sys.comm().get(), &ksp); CHKERRABORT(sys.comm().get(), ierr);
460 if (libMesh::on_command_line(
"--solver_system_names")) {
463 KSPSetOptionsPrefix(ksp, nm.c_str());
466 ierr = KSPSetOperators(ksp, mat, mat); CHKERRABORT(sys.comm().get(), ierr);
467 ierr = KSPSetFromOptions(ksp); CHKERRABORT(sys.comm().get(), ierr);
470 ierr = KSPGetPC(ksp, &pc); CHKERRABORT(sys.comm().get(), ierr);
471 ierr = PCSetFromOptions(pc); CHKERRABORT(sys.comm().get(), ierr);
474 START_LOG(
"KSPSolve",
"ComplexSolve");
477 ierr = KSPSolve(ksp, res_vec, sol_vec);
479 STOP_LOG(
"KSPSolve",
"ComplexSolve");
483 libMesh::NumericVector<Real>
488 first = sol_R.first_local_index(),
489 last = sol_R.last_local_index();
491 for (
unsigned int i=first; i<last; i++) {
492 sol_R.set(i, (*sol)( 2*i));
493 sol_I.set(i, (*sol)(2*i+1));
500 ierr = KSPDestroy(&ksp); CHKERRABORT(sys.comm().get(), ierr);
501 ierr = MatDestroy(&mat); CHKERRABORT(sys.comm().get(), ierr);
502 ierr = VecDestroy(&res_vec); CHKERRABORT(sys.comm().get(), ierr);
503 ierr = VecDestroy(&sol_vec); CHKERRABORT(sys.comm().get(), ierr);
505 STOP_LOG(
"solve_block_matrix()",
"ComplexSolve");
void residual_and_jacobian_blocked(const libMesh::NumericVector< Real > &X, libMesh::NumericVector< Real > &R, libMesh::SparseMatrix< Real > &J, MAST::Parameter *p=nullptr)
Assembles the residual and Jacobian of the N complex system of equations split into 2N real system of...
This class implements a system for solution of nonlinear systems.
void residual_and_jacobian_field_split(const libMesh::NumericVector< Real > &X_R, const libMesh::NumericVector< Real > &X_I, libMesh::NumericVector< Real > &R_R, libMesh::NumericVector< Real > &R_I, libMesh::SparseMatrix< Real > &J_R, libMesh::SparseMatrix< Real > &J_I)
void set_assembly(MAST::ComplexAssemblyBase &assemble)
sets the assembly object for this solver
This is a scalar function whose value can be changed and one that can be used as a design variable in...
libMesh::NumericVector< Real > & imag_solution(bool if_sens=false)
void clear_assembly()
clears the assembly object from this solver
virtual void solve_pc_fieldsplit()
solves the complex system of equations using PCFieldSplit
libMesh::SparseMatrix< Real > * matrix_A
The system matrix for standard eigenvalue problems.
virtual void solve_block_matrix(MAST::Parameter *p=nullptr)
solves the complex system of equations using block matrices.
libMesh::SparseMatrix< Real > * matrix_B
A second system matrix for generalized eigenvalue problems.
virtual ~ComplexSolverBase()
destructor
ComplexSolverBase()
default constructor
libMesh::NumericVector< Real > & real_solution(bool if_sens=false)
MAST::ComplexAssemblyBase * _assembly
Associated ComplexAssembly object that provides the element level quantities.
const MAST::NonlinearSystem & system() const