6 import java.io.BufferedReader;
7 import java.io.IOException;
8 import java.lang.reflect.InvocationTargetException;
9 import java.lang.reflect.Method;
11 import org.apache.commons.math.linear.Array2DRowRealMatrix;
12 import org.apache.commons.math.linear.ArrayRealVector;
13 import org.apache.commons.math.linear.DecompositionSolver;
14 import org.apache.commons.math.linear.LUDecompositionImpl;
15 import org.apache.commons.math.linear.RealMatrix;
16 import org.apache.commons.math.linear.RealVector;
32 private static final String DEBUG_TAG =
"QNTransientRBSystem";
35 private double nonlinear_tolerance;
38 private int n_newton_steps;
41 private double nominal_rho_min;
42 private double nominal_rho_max;
58 private double tau_prod_k;
61 private int _N_in_RB_solve;
79 throw new RuntimeException(
"ERROR: N cannot be larger than the number " +
"of basis functions in RB_solve");
82 throw new RuntimeException(
"ERROR: N must be greater than 0 in RB_solve");
88 RealMatrix RB_mass_matrix_N =
new Array2DRowRealMatrix(N, N);
89 for (
int q_m = 0; q_m <
getQm(); q_m++) {
90 RB_mass_matrix_N = RB_mass_matrix_N.add(
RB_M_q_matrix[q_m].getSubMatrix(0, N - 1, 0, N - 1).scalarMultiply(
94 RealMatrix RB_RHS_Aq_matrix =
new Array2DRowRealMatrix(N, N);
96 RealMatrix Base_RB_LHS_matrix = RB_mass_matrix_N.scalarMultiply(1. / dt);
98 for (
int q_a = 0; q_a <
getQa(); q_a++) {
99 double cached_theta_q_a =
thetaQa(q_a);
100 Base_RB_LHS_matrix = Base_RB_LHS_matrix.add(
RB_A_q_vector[q_a].getSubMatrix(0, N - 1, 0, N - 1)
102 RB_RHS_Aq_matrix = RB_RHS_Aq_matrix.add(
RB_A_q_vector[q_a].getSubMatrix(0, N - 1, 0, N - 1).scalarMultiply(
110 RealVector RB_u_bar =
new ArrayRealVector(N);
117 double error_bound_sum = 0.;
126 for (
int q_l = 0; q_l <
getQl(i); q_l++) {
134 RealVector RB_u_old =
new ArrayRealVector(N);
137 RealVector RB_delta_u =
new ArrayRealVector(N);
142 for (
int time_level = 1; time_level <=
fTotalTimesteps; time_level++) {
144 double t = time_level *
getdt();
149 RB_u_old = RB_u_bar.copy();
152 for (
int l = 0; l < n_newton_steps; ++l) {
155 RealVector RB_u_euler_theta = RB_u_bar.mapMultiply(
getEulerTheta()).add(
159 RealMatrix RB_LHS_matrix = Base_RB_LHS_matrix.copy();
162 for (
int i = 0; i < N; i++) {
163 for (
int j = 0; j < N; j++) {
164 double new_entry = RB_LHS_matrix.getEntry(i, j);
165 for (
int n = 0; n < N; n++) {
166 new_entry += cached_theta_c *
getEulerTheta() * RB_u_euler_theta.getEntry(n)
169 RB_LHS_matrix.setEntry(i, j, new_entry);
176 RealVector RB_rhs =
new ArrayRealVector(N);
178 for (
int q_f = 0; q_f <
getQf(); q_f++) {
183 RB_rhs = RB_rhs.add(RB_mass_matrix_N.operate(RB_u_bar).mapMultiply(-1. / dt));
184 RB_rhs = RB_rhs.add(RB_mass_matrix_N.operate(RB_u_old).mapMultiply(1. / dt));
187 RB_rhs = RB_rhs.add(RB_RHS_Aq_matrix.operate(RB_u_euler_theta));
190 for (
int i = 0; i < N; i++) {
191 double new_entry = RB_rhs.getEntry(i);
193 for (
int j = 0; j < N; j++) {
194 double RB_u_euler_theta_j = RB_u_euler_theta.getEntry(j);
196 for (
int n = 0; n < N; n++) {
197 new_entry -= cached_theta_c * RB_u_euler_theta.getEntry(n) * RB_u_euler_theta_j
201 RB_rhs.setEntry(i, new_entry);
204 DecompositionSolver solver =
new LUDecompositionImpl(RB_LHS_matrix).getSolver();
205 RB_delta_u = solver.solve(RB_rhs);
208 RB_u_bar = RB_u_bar.add(RB_delta_u);
211 double RB_delta_u_norm = RB_delta_u.getNorm();
213 if (RB_delta_u_norm < nonlinear_tolerance) {
217 if ((l == (n_newton_steps - 1)) && (RB_delta_u_norm > nonlinear_tolerance)) {
218 throw new RuntimeException(
"RB Newton loop did not converge");
242 for (
int q_l = 0; q_l <
getQl(i); q_l++) {
267 double tau_LB = (0.5 * rho_LB < 0.) ? 0.5 * rho_LB : 0.;
269 return getdt() * tau_prod_k / (1. - tau_LB *
getdt());
277 double tau_LB = (0.5 * rho_LB < 0.) ? 0.5 * rho_LB : 0.;
280 tau_prod_k *= (1. + tau_LB *
getdt()) / (1. - tau_LB *
getdt());
290 nonlinear_tolerance = nonlinear_tolerance_in;
297 return nonlinear_tolerance;
304 n_newton_steps = n_newton_steps_in;
311 return n_newton_steps;
322 Class<?> partypes[] =
new Class[1];
323 partypes[0] =
double[].class;
325 meth = oldAffFcnCl.getMethod(
"evaluateC", partypes);
326 }
catch (NoSuchMethodException nsme) {
327 throw new RuntimeException(
"getMethod for evaluateC failed", nsme);
332 Object arglist[] =
new Object[1];
336 theta_val = (Double) theta_obj;
337 }
catch (IllegalAccessException iae) {
338 throw new RuntimeException(iae);
339 }
catch (InvocationTargetException ite) {
340 throw new RuntimeException(ite.getCause());
343 return theta_val.doubleValue();
355 double residual_norm_sq = 0.;
358 residual_norm_sq += Math.pow(super.uncached_compute_residual_dual_norm(N), 2.);
361 RealVector RB_u_euler_theta = RB_solution.mapMultiply(
getEulerTheta()).add(
363 RealVector mass_coeffs = RB_solution.subtract(
old_RB_solution).mapMultiply(-1. / dt);
369 for (
int q_f = 0; q_f <
getQf(); q_f++) {
370 double cached_theta_q_f =
thetaQf(q_f);
371 for (
int n1 = 0; n1 < N; n1++) {
372 for (
int j1 = 0; j1 < N; j1++) {
373 residual_norm_sq += 2. * cached_theta_q_f * cached_theta_c * RB_u_euler_theta.getEntry(n1)
379 for (
int q_m = 0; q_m <
getQm(); q_m++) {
380 double cached_theta_q_m =
thetaQm(q_m);
381 for (
int i = 0; i < N; i++) {
382 for (
int n1 = 0; n1 < N; n1++) {
383 for (
int j1 = 0; j1 < N; j1++) {
384 residual_norm_sq += 2. * cached_theta_q_m * cached_theta_c * mass_coeffs.getEntry(i)
385 * RB_u_euler_theta.getEntry(n1) * RB_u_euler_theta.getEntry(j1)
392 for (
int q_a = 0; q_a <
getQa(); q_a++) {
393 double cached_theta_q_a =
thetaQa(q_a);
394 for (
int i = 0; i < N; i++) {
395 for (
int n1 = 0; n1 < N; n1++) {
396 for (
int j1 = 0; j1 < N; j1++) {
397 residual_norm_sq += 2. * cached_theta_q_a * cached_theta_c * RB_u_euler_theta.getEntry(i)
398 * RB_u_euler_theta.getEntry(n1) * RB_u_euler_theta.getEntry(j1)
405 for (
int n1 = 0; n1 < N; n1++) {
406 for (
int j1 = 0; j1 < N; j1++) {
407 double RB_u_euler_theta_1 = RB_u_euler_theta.getEntry(n1) * RB_u_euler_theta.getEntry(j1);
409 for (
int n2 = n1; n2 < N; n2++) {
410 int init_j2_index = (n2 == n1) ? j1 : 0;
411 for (
int j2 = init_j2_index; j2 < N; j2++) {
412 double RB_u_euler_theta_2 = RB_u_euler_theta.getEntry(n2) * RB_u_euler_theta.getEntry(j2);
414 double delta = ((n2 == n1) && (j2 == j1)) ? 1. : 2.;
416 residual_norm_sq += delta * cached_theta_c * cached_theta_c * RB_u_euler_theta_1
424 if (residual_norm_sq < 0) {
428 residual_norm_sq = Math.abs(residual_norm_sq);
431 return Math.sqrt(residual_norm_sq);
437 nominal_rho_min = nominal_rho_LB_in;
441 nominal_rho_max = nominal_rho_LB_in;
445 return nominal_rho_min;
449 return nominal_rho_max;
456 double mu_min =
getParams().getMinValue(0);
457 double mu_max =
getParams().getMaxValue(0);
458 double current_mu =
getParams().getCurrent()[0];
459 return (nominal_rho_max * (mu_max - current_mu) + nominal_rho_min * (current_mu - mu_min)) / (mu_max - mu_min);
472 qnScmSystem.set_n_basis_functions(_N_in_RB_solve);
477 double[] params =
new double[np + 1];
478 for (
int i = 0; i < np; i++) {
484 qnScmSystem.sys.getParams().setCurrent(params);
487 RealVector RB_u_euler_theta = RB_solution.mapMultiply(
getEulerTheta()).add(
491 qnScmSystem.set_current_RB_coeffs(RB_u_euler_theta);
493 return mRbScmSystem.get_SCM_LB();
505 super.readConfigurationRBAppMIT(infile);
507 double nonlinear_tolerance_in = infile.call(
"nonlinear_tolerance", 1.e-8);
510 int n_newton_steps_in = infile.call(
"n_newton_steps", 15);
513 double nominal_rho_min_in = infile.call(
"nominal_rho_min", 0);
516 double nominal_rho_max_in = infile.call(
"nominal_rho_max", 0);
519 Log.d(DEBUG_TAG,
"QNTransientRBSystem parameters from " + Const.parameters_filename +
":");
532 super.loadOfflineData_rbappmit(m);
539 Log.d(DEBUG_TAG,
"Starting read RB_trilinear_form.dat");
543 BufferedReader reader = m.getBufReader(
"RB_trilinear_form.dat");
545 String line = reader.readLine();
547 tokens = line.split(
" ");
555 for (
int i = 0; i < n_bfs; i++) {
556 for (
int j = 0; j < n_bfs; j++) {
557 for (
int l = 0; l < n_bfs; l++) {
564 Log.d(DEBUG_TAG,
"Finished reading RB_trilinear_form.dat");
572 BufferedReader reader = m.getBufReader(
"Fq_C_norms.dat");
573 String line = reader.readLine();
575 tokens = line.split(
" ");
583 for (
int q_f = 0; q_f <
getQf(); q_f++)
584 for (
int i = 0; i < n_bfs; i++) {
585 for (
int j = 0; j < n_bfs; j++) {
591 Log.d(DEBUG_TAG,
"Finished reading Fq_C_norms.dat");
598 BufferedReader reader = m.getBufReader(
"Mq_C_norms.dat");
600 tokens = reader.readLine().split(
" ");
609 for (
int q_m = 0; q_m <
getQm(); q_m++)
610 for (
int i = 0; i < n_bfs; i++)
611 for (
int j = 0; j < n_bfs; j++) {
612 for (
int k = 0; k < n_bfs; k++) {
618 Log.d(DEBUG_TAG,
"Finished reading Mq_C_norms.dat");
623 BufferedReader reader = m.getBufReader(
"Aq_C_norms.dat");
625 String[] tokens = reader.readLine().split(
" ");
634 for (
int q_a = 0; q_a <
getQa(); q_a++) {
635 for (
int i = 0; i < n_bfs; i++) {
636 for (
int n1 = 0; n1 < n_bfs; n1++) {
637 for (
int j1 = 0; j1 < n_bfs; j1++) {
644 Log.d(DEBUG_TAG,
"Finished reading Aq_C_norms.dat");
649 BufferedReader reader = m.getBufReader(
"C_C_norms.dat");
651 String[] tokens = reader.readLine().split(
" ");
660 for (
int ii = 0; ii < n_bfs; ii++) {
661 for (
int i = 0; i < n_bfs; i++) {
662 for (
int n1 = 0; n1 < n_bfs; n1++) {
663 for (
int j1 = 0; j1 < n_bfs; j1++) {
670 Log.d(DEBUG_TAG,
"Finished reading C_C_norms.dat");
double compute_output_dual_norm(int i, double t)
Compute the dual norm of the i^th output function at the current parameter value. ...
Base class for quadratically nonlinear RB systems including the SCM method for error bound computatio...
Utility helper class from rbAppMIT included for compatibility of rbAppMIT model loading.
double compute_residual_dual_norm(int N)
Compute the dual norm of the residual for the solution saved in RB_solution_vector.
double[][][] Fq_C_representor_norms
Vectors storing the residual representor inner products to be used in computing the residuals online...
This class provides the Online reduced basis functionality for linear parabolic problems.
double[][][][] C_C_representor_norms
void set_nominal_rho_min(double nominal_rho_LB_in)
int timestep
The current time-level, 0 <= _k <= _K.
void set_nonlinear_tolerance(double nonlinear_tolerance_in)
Set the nonlinear tolerance for Newton's method for both the truth and RB solves. ...
Parameters getParams()
Returns the system's parameters object.
double thetaQl(int k, int i)
void loadOfflineData_rbappmit(AModelManager m)
Override read_offline_data_from_files in order to read in the data for the nonlinear problem...
boolean return_rel_error_bound
Boolean flag to indicate whether RB_solve returns an absolute or relative error bound.
double get_SCM_from_AffineFunction()
A private helper function to get the SCM from AffineFunctions in the case that SCM_TYPE = NONE...
double thetaQa(int q)
Evaluate theta_q_a (for the q^th bilinear form) at the current parameter.
RealVector old_RB_solution
RBSystem has a member RB_solution, we also need old_RB_solution here.
This class serves as base class for accessing various types of models at different locations...
double residual_scaling_denom(double rho_LB)
Override appropriate for quadratically nonlinear error bounds.
RealMatrix[] RB_M_q_matrix
Dense matrices for the RB computations.
double[][][][] Aq_C_representor_norms
RealVector[] timestepRBSolutions
The solution coefficients at each time level from the most recent RB_solve.
int getQf()
TODO: if all affine_functions implement the IAffineFunctions interface, just call the getQf method of...
double residual_scaling_numer(double rho_LB)
Override appropriate for quadratically nonlinear error bounds.
double[][][] RB_trilinear_form
double get_nominal_rho_LB()
Get the nominal stability factor lower bound.
RealVector RB_solution
The RB solution vector.
void setTimeStep(int k_in)
double getEulerTheta()
Get/set euler_theta, parameter that determines the temporal discretization.
double getdt()
Gets dt, the time-step size.
Provides a Log class imitating the Android Log class when not used on android systems.
int get_n_newton_steps()
Set the maximum number of Newton steps for both the truth and RB solves.
double eval_theta_c()
Evaluate theta_c (for the quadratic nonlinearity) at the current parameter.
double[][] RB_output_error_bounds_all_k
The output error bounds at all time levels.
double get_nonlinear_tolerance()
Get the nonlinear tolerance for Newton's method.
double get_nominal_rho_max()
double get_nominal_rho_min()
RealMatrix[] RB_A_q_vector
Dense matrices for the RB computations.
double[][] RB_outputs_all_k
The outputs at all time levels.
RealVector[][] RB_output_vectors
The vectors storing the RB output vectors.
double RB_solve(int N)
Perform online solve for current_params with the N basis functions.
double get_SCM_lower_bound()
double[] error_bound_all_k
The error bound for the field variable at each time level.
RealVector[] RB_F_q_vector
Dense vector for the RHS.
void set_nominal_rho_max(double nominal_rho_LB_in)
double thetaQm(int i)
Evaluate theta_q_m (for the q^th mass matrix term) at the current parameter.
void readConfigurationRBAppMIT(GetPot infile)
RBSCMSystem mRbScmSystem
A reference to the SCM system.
double[][][][] Mq_C_representor_norms
void set_n_newton_steps(int n_newton_steps_in)
Set the maximum number of Newton steps for both the truth and RB solves.
int getQl(int output_index)
TODO: if all affine_functions implement the IAffineFunctions interface, just call the getQl method of...
int fTotalTimesteps
Total number of time-steps.
This class provides the Online reduced basis functionality for quadratically nonlinear time-dependent...