JaRMoS  1.1
Java Reduced Model Simulations
 All Classes Namespaces Files Functions Variables Enumerator Groups Pages
ComplexRBSystem.java
Go to the documentation of this file.
1 package rb;
2 
3 // rbAPPmit: An Android front-end for the Certified Reduced Basis Method
4 // Copyright (C) 2010 David J. Knezevic and Phuong Huynh
5 //
6 // This file is part of rbAPPmit
7 //
8 // @ref rbappmit is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 //
13 // @ref rbappmit is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with rbAPPmit. If not, see <http://www.gnu.org/licenses/>.
20 
23 import jarmos.Log;
28 
29 import java.io.BufferedReader;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.lang.reflect.Array;
33 import java.lang.reflect.InvocationTargetException;
34 import java.lang.reflect.Method;
35 
36 import org.apache.commons.math.complex.Complex;
37 import org.apache.commons.math.linear.Array2DRowFieldMatrix;
38 import org.apache.commons.math.linear.ArrayFieldVector;
39 import org.apache.commons.math.linear.FieldMatrix;
40 import org.apache.commons.math.linear.FieldVector;
41 
48 public class ComplexRBSystem extends RBSystem {
49 
50  // Logging tag
51  private static final String DEBUG_TAG = "ComplexRBSystem";
52 
53  public Complex[] RB_outputs;
54  public Complex[] RB_output_error_bounds;
55 
56  protected FieldVector<Complex> RB_solution;
57 
58  public Complex[][] output_dual_norms;
59  protected FieldVector<Complex>[][] RB_output_vectors;
60  protected FieldMatrix<Complex>[] RB_A_q_vector;
61  protected FieldVector<Complex>[] RB_F_q_vector;
62 
63  protected FieldVector<Complex> theta_a;
64 
65  protected Complex[] Fq_representor_norms;
66  protected Complex[][][] Fq_Aq_representor_norms;
67  protected Complex[][][] Aq_Aq_representor_norms;
68 
69  protected Complex[][][] Z_vector;
70  protected Complex[][] uL_vector;
71 
72  @Override
73  public void loadOfflineData_rbappmit(AModelManager m) throws IOException {
74 
75  isReal = false;
76 
77  // Find out dimension of the RB space
78  {
79  BufferedReader reader = m.getBufReader("n_bfs.dat");
80 
81  set_n_basis_functions(Integer.parseInt(reader.readLine()));
82 
83  reader.close();
84  }
85 
86  Log.d(DEBUG_TAG, "Finished reading n_bfs.dat");
87 
88  // Read in output data
89  if (getNumOutputs() > 0) {
90  // Get output dual norms
91  {
92  RB_output_vectors = (FieldVector<Complex>[][]) new FieldVector<?>[getNumOutputs()][];
93  output_dual_norms = new Complex[getNumOutputs()][];
94  for (int i = 0; i < getNumOutputs(); i++) {
95 
96  String[] dual_norms_tokens;
97  {
98  BufferedReader reader = m
99  .getBufReader("output_" + String.format("%03d", i) + "_dual_norms.dat");
100 
101  dual_norms_tokens = reader.readLine().split(" ");
102  reader.close();
103  }
104 
105  {
106  int Q_l_hat = getQl(i) * (getQl(i) + 1) / 2;
107  output_dual_norms[i] = new Complex[Q_l_hat];
108  for (int q = 0; q < Q_l_hat; q++) {
109  output_dual_norms[i][q] = new Complex(Double.parseDouble(dual_norms_tokens[q]),
110  Double.parseDouble(dual_norms_tokens[Q_l_hat + q]));
111  }
112  }
113 
114  {
115  RB_output_vectors[i] = (FieldVector<Complex>[]) new FieldVector<?>[getQl(i)];
116  String[] output_i_tokens;
117  for (int q_l = 0; q_l < getQl(i); q_l++) {
118  // Now read in the RB output vectors
119  {
120  BufferedReader reader_i = m.getBufReader("output_" + String.format("%03d", i) + "_"
121  + String.format("%03d", q_l) + ".dat");
122 
123  output_i_tokens = reader_i.readLine().split(" ");
124  reader_i.close();
125  }
126 
127  RB_output_vectors[i][q_l] = new ArrayFieldVector<Complex>(getNBF(), new Complex(0d, 0d));
128  for (int j = 0; j < getNBF(); j++) {
129  RB_output_vectors[i][q_l].setEntry(
130  j,
131  new Complex(Double.parseDouble(output_i_tokens[j]), Double
132  .parseDouble(output_i_tokens[getNBF() + j])));
133  }
134  }
135  }
136  }
137  }
138  Log.d(DEBUG_TAG, "Finished reading output data");
139  } else
140  Log.d(DEBUG_TAG, "No output data set. (get_n_outputs() == 0)");
141 
142  /*
143  * // Read in the inner product matrix { InputStreamReader isr; String
144  * dataString = directory_name + "/RB_inner_product_matrix.dat";
145  *
146  * if(!isAssetFile) { HttpGet request = new HttpGet(dataString);
147  * HttpResponse response = client.execute(request); isr = new
148  * InputStreamReader(response.getEntity() .getContent()); } else { //
149  * Read from assets isr = new InputStreamReader(
150  * context.getAssets().open(dataString)); } BufferedReader
151  * BufferedReader reader = new BufferedReader(isr,buffer_size);
152  *
153  * String String line = reader.readLine(); String[] tokens =
154  * line.split(" ");
155  *
156  * // Set the size of the inner product matrix RB_inner_product_matrix =
157  * new Array2DRowRealMatrix(n_bfs, n_bfs);
158  *
159  * // Fill the matrix int count = 0; for (int i = 0; i < n_bfs; i++) for
160  * (int j = 0; j < n_bfs; j++) { RB_inner_product_matrix.setEntry(i, j,
161  * Double .parseDouble(tokens[count])); count++; } reader.close(); }
162  *
163  * Log.d(DEBUG_TAG, "Finished reading RB_inner_product_matrix.dat");
164  */
165 
166  // Read in the F_q vectors
167  {
168  RB_F_q_vector = (FieldVector<Complex>[]) new FieldVector<?>[getQf()];
169  String[] tokens;
170  for (int q_f = 0; q_f < getQf(); q_f++) {
171  {
172  BufferedReader reader = m.getBufReader("RB_F_" + String.format("%03d", q_f) + ".dat");
173 
174  tokens = reader.readLine().split(" ");
175  reader.close();
176  }
177 
178  // Set the size of the inner product matrix
179  RB_F_q_vector[q_f] = new ArrayFieldVector<Complex>(getNBF(), new Complex(0d, 0d));
180 
181  // Fill the vector
182  for (int i = 0; i < getNBF(); i++) {
183  RB_F_q_vector[q_f].setEntry(i,
184  new Complex(Double.parseDouble(tokens[i]), Double.parseDouble(tokens[getNBF() + i])));
185  }
186  }
187  Log.d(DEBUG_TAG, "Finished reading RB_F_q data");
188  }
189 
190  // Read in the A_q matrices
191  {
192  RB_A_q_vector = (FieldMatrix<Complex>[]) Array.newInstance(FieldMatrix.class, getQa());// (FieldMatrix<Complex>[])
193  // new
194  // FieldMatrix<?>[get_Q_a()];
195  String[] tokens;
196  for (int q_a = 0; q_a < getQa(); q_a++) {
197  {
198  BufferedReader reader = m.getBufReader("RB_A_" + String.format("%03d", q_a) + ".dat");
199  tokens = reader.readLine().split(" ");
200  reader.close();
201  }
202 
203  // Set the size of the inner product matrix
204  RB_A_q_vector[q_a] = new Array2DRowFieldMatrix<Complex>((new Complex(0, 0)).getField(), getNBF(),
205  getNBF());
206 
207  // Fill the vector
208  int count = 0;
209  for (int i = 0; i < getNBF(); i++)
210  for (int j = 0; j < getNBF(); j++) {
211  RB_A_q_vector[q_a].setEntry(
212  i,
213  j,
214  new Complex(Double.parseDouble(tokens[count]), Double.parseDouble(tokens[count
215  + getNBF() * getNBF()])));
216  count++;
217  }
218  }
219  Log.d(DEBUG_TAG, "Finished reading RB_A_q data");
220  }
221 
222  // Read in F_q representor norm data
223  {
224  BufferedReader reader = m.getBufReader("Fq_norms.dat");
225 
226  String[] tokens = reader.readLine().split(" ");
227  reader.close();
228 
229  // Declare the array
230  int Q_f_hat = getQf() * (getQf() + 1) / 2;
231  Fq_representor_norms = new Complex[Q_f_hat];
232 
233  // Fill it
234  for (int i = 0; i < Q_f_hat; i++) {
235  Fq_representor_norms[i] = new Complex(Double.parseDouble(tokens[i * 2 + 0]),
236  Double.parseDouble(tokens[i * 2 + 1]));
237  }
238 
239  Log.d(DEBUG_TAG, "Finished reading Fq_norms.dat");
240  }
241 
242  // Read in Fq_Aq representor norm data
243  {
244  BufferedReader reader = m.getBufReader("Fq_Aq_norms.dat");
245 
246  String[] tokens = reader.readLine().split(" ");
247  reader.close();
248  reader = null;
249 
250  // Declare the array
251  Fq_Aq_representor_norms = new Complex[getQf()][getQa()][getNBF()];
252 
253  double[][][] Rdata = new double[getQf()][getQa()][getNBF()];
254  double[][][] Idata = new double[getQf()][getQa()][getNBF()];
255  // Fill it
256  int count = 0;
257  for (int q_f = 0; q_f < getQf(); q_f++)
258  for (int q_a = 0; q_a < getQa(); q_a++) {
259  for (int i = 0; i < getNBF(); i++) {
260  Rdata[q_f][q_a][i] = Double.parseDouble(tokens[count]);
261  count++;
262  }
263  for (int i = 0; i < getNBF(); i++) {
264  Idata[q_f][q_a][i] = Double.parseDouble(tokens[count]);
265  count++;
266  }
267  }
268 
269  for (int q_f = 0; q_f < getQf(); q_f++)
270  for (int q_a = 0; q_a < getQa(); q_a++)
271  for (int i = 0; i < getNBF(); i++)
272  Fq_Aq_representor_norms[q_f][q_a][i] = new Complex(Rdata[q_f][q_a][i], Idata[q_f][q_a][i]);
273 
274  Log.d(DEBUG_TAG, "Finished reading Fq_Aq_norms.dat");
275  }
276 
277  MathObjectReader mr = m.getMathObjReader();
278  // Read in Aq_Aq representor norm data
279  {
280  // Declare the array
281  int Q_a_hat = getQa() * (getQa() + 1) / 2;
282  Aq_Aq_representor_norms = new Complex[Q_a_hat][getNBF()][getNBF()];
283 
284  int count = 0;
285  double[][] Rdata2 = null, Idata2 = null;
286  for (int i = 0; i < getQa(); i++)
287  for (int j = i; j < getQa(); j++) {
288  String file = "Aq_Aq_" + String.format("%03d", i) + "_" + String.format("%03d", j) + "_norms.bin";
289 
290  int n = getNBF();
291  InputStream in = m.getInStream(file);
292  try {
293  Rdata2 = mr.readRawDoubleMatrix(in, n, n);
294  Idata2 = mr.readRawDoubleMatrix(in, n, n);
295  } catch (IOException io) {
296  Log.e("ComplexRBSystem", "IOException with file " + file, io);
297  } finally {
298  in.close();
299  in = null;
300  }
301  for (int k = 0; k < n; k++)
302  for (int l = 0; l < n; l++)
303  Aq_Aq_representor_norms[count][k][l] = new Complex(Rdata2[k][l], Idata2[k][l]);
304 
305  count++;
306  }
307  Log.d(DEBUG_TAG, "Finished reading Aq_Aq_norms.dat");
308  }
309 
310  // // Read calN number
311  // {
312  // if (getNumFields() > 0) {
313  // BufferedReader reader = m.getBufReader("calN.dat");
314  //
315  // String line = reader.readLine();
316  //
317  // set_calN(Integer.parseInt(line));
318  // reader.close();
319  // }
320  //
321  // Log.d(DEBUG_TAG, "Finished reading calN.dat");
322  // }
323 
324  int n = getGeometry().getNumVertices();
325  // Reading uL data
326  {
327  if (getQuL() > 0) {
328  uL_vector = new Complex[getQuL()][n];
329  float[] Rdata3, Idata3;
330  for (int q_uL = 0; q_uL < getQuL(); q_uL++) {
331  InputStream in = m.getInStream("uL_" + String.format("%03d", q_uL) + ".bin");
332  try {
333  Rdata3 = mr.readRawFloatVector(in, n);
334  Idata3 = mr.readRawFloatVector(in, n);
335  } finally {
336  in.close();
337  }
338  for (int i = 0; i < n; i++)
339  uL_vector[q_uL][i] = new Complex(Rdata3[i], Idata3[i]);
340  }
341  }
342  Log.d(DEBUG_TAG, "Finished reading uL.dat");
343  }
344 
345  // Read in Z data
346  {
347  if (getNumDoFFields() > 0) {
348  Z_vector = new Complex[getNumDoFFields()][getNBF()][n];
349  float[] Rdata3, Idata3;
350  for (int imf = 0; imf < getNumDoFFields(); imf++)
351  for (int inbfs = 0; inbfs < getNBF(); inbfs++) {
352  InputStream in = m.getInStream("Z_" + String.format("%03d", imf) + "_"
353  + String.format("%03d", inbfs) + ".bin");
354  try {
355  Rdata3 = mr.readRawFloatVector(in, n);
356  Idata3 = mr.readRawFloatVector(in, n);
357  } finally {
358  in.close();
359  }
360  for (int i = 0; i < n; i++)
361  Z_vector[imf][inbfs][i] = new Complex(Rdata3[i], Idata3[i]);
362  }
363  }
364  Log.d(DEBUG_TAG, "Finished reading Z.dat");
365  }
366 
368  }
369 
370  protected void initialize_data_vectors() {
371  // Also, resize RB_outputs and RB_output_error_error_bounds arrays
372  RB_outputs = new Complex[getNumOutputs()];
373  RB_output_error_bounds = new Complex[getNumOutputs()];
374  }
375 
376  @Override
377  public double RB_solve(int N) {
378 
379  current_N = N;
380 
382 
383  if (N > getNBF()) {
384  throw new RuntimeException("ERROR: N cannot be larger than the number " + "of basis functions in RB_solve");
385  }
386  if (N == 0) {
387  throw new RuntimeException("ERROR: N must be greater than 0 in RB_solve");
388  }
389 
390  // Assemble the RB system
391  FieldMatrix<Complex> RB_system_matrix_N = new Array2DRowFieldMatrix<Complex>((new Complex(0, 0)).getField(), N,
392  N);
393 
394  for (int q_a = 0; q_a < getQa(); q_a++) {
395  RB_system_matrix_N = RB_system_matrix_N.add(RB_A_q_vector[q_a].getSubMatrix(0, N - 1, 0, N - 1)
396  .scalarMultiply(theta_a.getEntry(q_a)));
397  // scalarMultiply(complex_eval_theta_q_a(q_a) ) );
398  }
399 
400  // Assemble the RB rhs
401  FieldVector<Complex> RB_rhs_N = new ArrayFieldVector<Complex>(N, new Complex(0d, 0d));
402 
403  for (int q_f = 0; q_f < getQf(); q_f++) {
404  // Note getSubVector takes an initial index and the number of
405  // entries
406  // i.e. the interface is a bit different to getSubMatrix
407  RB_rhs_N = RB_rhs_N.add(RB_F_q_vector[q_f].getSubVector(0, N).mapMultiply(complex_eval_theta_q_f(q_f)));
408  }
409 
410  // Solve the linear system by Gaussian elimination
411 
412  RB_solution = new ArrayFieldVector<Complex>(N, new Complex(0., 0.));
413  for (int j = 1; j < N; j++)
414  for (int i = j; i < N; i++) {
415  Complex m = RB_system_matrix_N.getEntry(i, j - 1).divide(RB_system_matrix_N.getEntry(j - 1, j - 1));
416  for (int k = 0; k < N; k++)
417  RB_system_matrix_N.setEntry(
418  i,
419  k,
420  RB_system_matrix_N.getEntry(i, k).subtract(
421  RB_system_matrix_N.getEntry(j - 1, k).multiply(m)));
422  RB_rhs_N.setEntry(i, RB_rhs_N.getEntry(i).subtract(m.multiply(RB_rhs_N.getEntry(j - 1))));
423  }
424  RB_solution.setEntry(N - 1, RB_rhs_N.getEntry(N - 1).divide(RB_system_matrix_N.getEntry(N - 1, N - 1)));
425  for (int j = N - 2; j >= 0; j--) {
426  Complex m = new Complex(0., 0.);
427  for (int i = j + 1; i < N; i++)
428  m = m.add(RB_system_matrix_N.getEntry(j, i).multiply(RB_solution.getEntry(i)));
429  RB_solution.setEntry(j, (RB_rhs_N.getEntry(j).subtract(m)).divide(RB_system_matrix_N.getEntry(j, j)));
430  }
431 
432  // Evaluate the dual norm of the residual for RB_solution_vector
433  double epsilon_N = compute_residual_dual_norm(N);
434 
435  // Get lower bound for coercivity constant
436  double alpha_LB = get_SCM_lower_bound();
437 
438  // If SCM lower bound is negative
439  if (alpha_LB < 0) { // Get an upper bound instead
440  alpha_LB = get_SCM_upper_bound();
441  }
442 
443  // Store (absolute) error bound
444  double abs_error_bound = epsilon_N / residual_scaling_denom(alpha_LB);
445 
446  // Compute the norm of RB_solution
447  /*
448  * RealMatrix RB_inner_product_matrix_N =
449  * RB_inner_product_matrix.getSubMatrix(0, N-1, 0, N-1);
450  */
451 
452  double RB_solution_norm = 0.0d;
453  for (int i = 0; i < N; i++)
454  RB_solution_norm += ((RB_solution.getEntry(i)).multiply((RB_solution.getEntry(i)).conjugate())).getReal();
455  RB_solution_norm = Math.sqrt(RB_solution_norm);
456 
457  // Now compute the outputs and associated errors
458  FieldVector<Complex> RB_output_vector_N = new ArrayFieldVector<Complex>(N, new Complex(0d, 0d));
459  for (int i = 0; i < getNumOutputs(); i++) {
460  RB_outputs[i] = new Complex(0., 0.);
461 
462  RB_output_vector_N = (RB_output_vectors[i][0].getSubVector(0, N)).mapMultiply(complex_eval_theta_q_l(i, 0));
463  for (int q_l = 1; q_l < getQl(i); q_l++)
464  RB_output_vector_N = RB_output_vector_N.add((RB_output_vectors[i][q_l].getSubVector(0, N))
465  .mapMultiply(complex_eval_theta_q_l(i, q_l)));
466  for (int j = 0; j < N; j++)
467  RB_outputs[i] = RB_outputs[i].add((RB_output_vector_N.getEntry(j).conjugate()).multiply((RB_solution
468  .getEntry(j))));
469 
470  RB_output_error_bounds[i] = new Complex(compute_output_dual_norm(i, 0) // Zero
471  // means
472  // no
473  // time
474  // used
475  // here
476  * abs_error_bound, compute_output_dual_norm(i, 0) // Zero
477  // means
478  // no
479  // time
480  // used
481  // here
482  * abs_error_bound);
483  }
484 
486 
487  return (return_rel_error_bound ? abs_error_bound / RB_solution_norm : abs_error_bound);
488  }
489 
490  @Override
491  protected double compute_residual_dual_norm(int N) {
492 
493  // Use the stored representor inner product values
494  // to evaluate the residual norm
495  double res_ff = 0;
496  double res_af = 0;
497  double res_aa = 0;
498 
499  int q = 0;
500  for (int q_f1 = 0; q_f1 < getQf(); q_f1++) {
501  for (int q_f2 = q_f1; q_f2 < getQf(); q_f2++) {
502  double delta = (q_f1 == q_f2) ? 1. : 2.;
503  res_ff += delta
504  * ((complex_eval_theta_q_f(q_f1).multiply(complex_eval_theta_q_f(q_f2).conjugate()))
505  .multiply(Fq_representor_norms[q])).getReal();
506  q++;
507  }
508  }
509 
510  for (int q_f = 0; q_f < getQf(); q_f++) {
511  for (int q_a = 0; q_a < getQa(); q_a++) {
512  for (int i = 0; i < N; i++) {
513  res_af += 2. * (get_complex_soln_coeff(i).conjugate().multiply(
514  // complex_eval_theta_q_f(q_f).multiply(complex_eval_theta_q_a(q_a).conjugate())
515  complex_eval_theta_q_f(q_f).multiply(theta_a.getEntry(q_a).conjugate()))
516  .multiply(Fq_Aq_representor_norms[q_f][q_a][i])).getReal();
517  }
518  }
519  }
520 
521  q = 0;
522  for (int q_a1 = 0; q_a1 < getQa(); q_a1++) {
523  for (int q_a2 = q_a1; q_a2 < getQa(); q_a2++) {
524  for (int i = 0; i < N; i++) {
525  for (int j = 0; j < N; j++) {
526  double delta = (q_a1 == q_a2) ? 1. : 2.;
527  res_aa += delta
528  * ((get_complex_soln_coeff(i).conjugate().multiply(get_complex_soln_coeff(j)))
529  .multiply(
530  // (complex_eval_theta_q_a(q_a1).conjugate().multiply(complex_eval_theta_q_a(q_a2)))
531  (theta_a.getEntry(q_a1).conjugate().multiply(theta_a.getEntry(q_a2))))
532  .multiply(Aq_Aq_representor_norms[q][i][j])).getReal();
533  }
534  }
535  q++;
536  }
537  }
538 
539  double residual_norm_sq = res_ff + res_af + res_aa;
540 
541  if (residual_norm_sq < 0.) {
542  // Sometimes this is negative due to rounding error,
543  // but error is on the order of 1.e-10, so shouldn't
544  // affect error bound much...
545  residual_norm_sq = Math.abs(residual_norm_sq);
546  }
547 
548  return Math.sqrt(residual_norm_sq);
549  }
550 
555  @Override
556  protected double compute_output_dual_norm(int i, double t) {
557 
558  // Use the stored representor inner product values
559  // to evaluate the output dual norm
560  double output_norm_sq = 0.;
561 
562  int q = 0;
563  for (int q_l1 = 0; q_l1 < getQl(i); q_l1++) {
564  for (int q_l2 = q_l1; q_l2 < getQl(i); q_l2++) {
565  if (q_l1 == q_l2)
566  output_norm_sq += 1. * ((complex_eval_theta_q_l(i, q_l1).multiply(complex_eval_theta_q_l(i, q_l2)
567  .conjugate())).multiply(output_dual_norms[i][q])).getReal();
568  else
569  output_norm_sq += 2. * ((complex_eval_theta_q_l(i, q_l1).multiply(complex_eval_theta_q_l(i, q_l2)
570  .conjugate())).multiply(output_dual_norms[i][q])).getReal();
571  q++;
572  }
573  }
574 
575  return Math.sqrt(output_norm_sq);
576  }
577 
578  Complex get_complex_soln_coeff(int i) {
579  return RB_solution.getEntry(i);
580  }
581 
582  @Override
583  public double[][] get_RBsolution() {
584  Complex[] c = RB_solution.toArray();
585  double[][] d = new double[2][c.length];
586  for (int i = 0; i < c.length; i++) {
587  d[0][i] = c[i].getReal();
588  d[1][i] = c[i].getImaginary();
589  }
590  return d;
591  }
592 
593  @Override
594  public double get_RB_output(int n_output, boolean Rpart) {
595  if (Rpart)
596  return RB_outputs[n_output].getReal();
597  else
598  return RB_outputs[n_output].getImaginary();
599  }
600 
601  @Override
602  public double get_RB_output_error_bound(int n_output, boolean Rpart) {
603  if (Rpart)
604  return RB_output_error_bounds[n_output].getReal();
605  else
606  return RB_output_error_bounds[n_output].getImaginary();
607  }
608 
618  @Override
620  int N = RB_solution.getDimension();
621  SimulationResult res = new SimulationResult(1);
622 
623  int fnumcnt = 0;
624  for (FieldDescriptor sftype : logicalFieldTypes) {
625  if (fnumcnt + sftype.Type.requiredDoFFields > getNumDoFFields()) {
626  throw new RuntimeException("Too many output fields used by current "
627  + "SolutionFieldTypes set in RBSystem. Check your model.xml.");
628  }
629  int numDoF = Z_vector[fnumcnt][0].length;
630  switch (sftype.Type) {
631  case ComplexValue: {
632  ComplexSolutionField f = new ComplexSolutionField(sftype, numDoF);
633  Complex tmpval;
634  for (int nodenr = 0; nodenr < numDoF; nodenr++) {
635  tmpval = new Complex(0., 0.);
636  for (int rbdim = 0; rbdim < N; rbdim++) {
637  tmpval = tmpval.add(Z_vector[fnumcnt][rbdim][nodenr].multiply(get_complex_soln_coeff(rbdim)));
638  }
639  f.setComplexValue(nodenr, tmpval);
640  }
641  if (getQuL() > 0) {
642  for (int q_uL = 0; q_uL < getQuL(); q_uL++)
643  for (int i = 0; i < numDoF; i++) {
644  f.addComplexValue(i, (float) uL_vector[q_uL][i].getReal(),
645  (float) uL_vector[q_uL][i].getImaginary());
646  }
647  }
648  res.addField(f);
649  break;
650  }
651  default:
652  throw new RuntimeException("Invalid/unimplemented solution field type '" + sftype.Type
653  + "' for complex RB system");
654  }
655  /*
656  * Increase field counter by the amount the current solution field
657  * used
658  */
659  fnumcnt += sftype.Type.requiredDoFFields;
660  }
661  for (MeshTransform m : transforms) {
662  res.addTransform(m);
663  }
664  return res;
665  }
666 
667  @Override
669  int N = RB_sweep_solution[0][0].length;
670  int numSweep = RB_sweep_solution.length;
671 
672  /*
673  * Preparations
674  */
675  Complex[][] RB_sweep_sol = new Complex[numSweep][N];
676  for (int i = 0; i < numSweep; i++)
677  for (int j = 0; j < N; j++)
678  RB_sweep_sol[i][j] = new Complex(RB_sweep_solution[i][0][j], RB_sweep_solution[i][1][j]);
679  SimulationResult res = new SimulationResult(numSweep);
680  int fnumcnt = 0;
681  for (FieldDescriptor sftype : logicalFieldTypes) {
682  if (fnumcnt + sftype.Type.requiredDoFFields > getNumDoFFields()) {
683  throw new RuntimeException("Too many output fields used by current "
684  + "SolutionFieldTypes set in RBSystem. Check your model.xml.");
685  }
686  int numDoF = Z_vector[fnumcnt][0].length;
687  switch (sftype.Type) {
688  case ComplexValue: {
689  ComplexSolutionField f = new ComplexSolutionField(sftype, numDoF * numSweep);
690  Complex tmpval;
691  for (int iSweep = 0; iSweep < numSweep; iSweep++) {
692  for (int i = 0; i < numDoF; i++) {
693  tmpval = new Complex(0., 0.);
694  for (int rbdim = 0; rbdim < N; rbdim++) {
695  tmpval = tmpval.add(Z_vector[fnumcnt][rbdim][i].multiply(RB_sweep_sol[iSweep][rbdim]));
696  }
697  f.setComplexValue(iSweep * numDoF + i, tmpval);
698  }
699  }
700  if (getQuL() > 0) {
701  for (int q_uL = 0; q_uL < getQuL(); q_uL++)
702  for (int iSweep = 0; iSweep < numSweep; iSweep++)
703  for (int nodenr = 0; nodenr < numDoF; nodenr++) {
704  f.addComplexValue(iSweep * numDoF + nodenr, uL_vector[q_uL][nodenr]);
705  }
706  }
707  res.addField(f);
708  break;
709  }
710  default:
711  throw new RuntimeException("Invalid/unimplemented solution field type '" + sftype.Type
712  + "' for complex RB system sweep");
713  }
714  /*
715  * Increase field counter by the amount the current solution field
716  * used
717  */
718  fnumcnt += sftype.Type.requiredDoFFields;
719  }
720  for (MeshTransform m : transforms) {
721  res.addTransform(m);
722  }
723  return res;
724  }
725 
726  public boolean is_derived_output() {
727  Method meth;
728 
729  try {
730  Class<?> partypes[] = null;
731  meth = oldAffFcnCl.getMethod("is_derived_output", partypes);
732  } catch (NoSuchMethodException nsme) {
733  return false;
734  }
735 
736  try {
737  Object arglist[] = null;
738  Object theta_obj = meth.invoke(oldAffFcnObj, arglist);
739  boolean val = (Boolean) theta_obj;
740  return val;
741  } catch (IllegalAccessException iae) {
742  throw new RuntimeException(iae);
743  } catch (InvocationTargetException ite) {
744  throw new RuntimeException(ite.getCause());
745  }
746  }
747 
748  public void cal_derived_output() {
749  if (is_derived_output()) {
750  Method meth;
751 
752  try {
753 
754  Class<?> partypes[] = new Class[1];
755  partypes[0] = double[].class;
756 
757  meth = oldAffFcnCl.getMethod("cal_derived_output", partypes);
758  } catch (NoSuchMethodException nsme) {
759  throw new RuntimeException("getMethod for cal_derived_output failed", nsme);
760  }
761 
762  try {
763 
764  Object arglist[] = new Object[1];
765  double[] input = new double[4];
766  for (int i = 0; i < getNumOutputs(); i++) {
767  input[0] = RB_outputs[i].getReal();
768  input[1] = RB_outputs[i].getImaginary();
769  input[2] = RB_output_error_bounds[i].getReal();
770  input[3] = RB_output_error_bounds[i].getImaginary();
771 
772  arglist[0] = input;
773 
774  Object theta_obj = meth.invoke(oldAffFcnObj, arglist);
775  double[] output = (double[]) theta_obj;
776  RB_outputs[i] = new Complex(output[0], output[1]);
777  RB_output_error_bounds[i] = new Complex(output[2], output[3]);
778  }
779  } catch (IllegalAccessException iae) {
780  throw new RuntimeException(iae);
781  } catch (InvocationTargetException ite) {
782  throw new RuntimeException(ite.getCause());
783  }
784 
785  }
786  }
787 }
Complex[][] output_dual_norms
double get_RB_output_error_bound(int n_output, boolean Rpart)
GeometryData getGeometry()
The model&#39;s geometry data.
Definition: ModelBase.java:69
int getNumOutputs()
Definition: RBSystem.java:612
Complex complex_eval_theta_q_f(int q)
Definition: RBSystem.java:317
int getNumDoFFields()
Returns the number of degree-of-freedom fields generated/computed by the model.
Definition: ModelBase.java:78
double[][] get_RBsolution()
FieldVector< Complex > theta_a
This class provides the Online stage for the reduced basis method for elliptic steady state problems...
Definition: RBSystem.java:54
int current_N
Definition: RBSystem.java:80
Represents the results of a simulation.
FieldMatrix< Complex >[] RB_A_q_vector
Complex[] Fq_representor_norms
Reading matrices and vectors with a bunch of convenient overloads for different sources and output fo...
Complex[][][] Aq_Aq_representor_norms
double compute_output_dual_norm(int i, double t)
Complex[] RB_output_error_bounds
boolean return_rel_error_bound
Boolean flag to indicate whether RB_solve returns an absolute or relative error bound.
Definition: RBSystem.java:209
FieldVector< Complex > complex_eval_theta_q_a()
Definition: RBSystem.java:238
void set_n_basis_functions(int _N)
Definition: RBSystem.java:1591
This class serves as base class for accessing various types of models at different locations...
FieldVector< Complex > RB_solution
int getQf()
TODO: if all affine_functions implement the IAffineFunctions interface, just call the getQf method of...
Definition: RBSystem.java:638
FieldVector< Complex >[][] RB_output_vectors
Object oldAffFcnObj
Definition: RBSystem.java:144
FieldDescriptor[] logicalFieldTypes
The logical output fields of the model, each collecting one ore more model DoF&#39;s into a related unit...
Definition: ModelBase.java:26
FieldVector< Complex >[] RB_F_q_vector
SimulationResult getSimulationResults()
Returns the results of the complex RB simulation.
Provides a Log class imitating the Android Log class when not used on android systems.
Definition: Log.java:11
double get_RB_output(int n_output, boolean Rpart)
RB system class for complex-valued fields.
Complex[][][] Fq_Aq_representor_norms
Complex get_complex_soln_coeff(int i)
double get_SCM_upper_bound()
Definition: RBSystem.java:563
double[][][] RB_sweep_solution
Definition: RBSystem.java:203
int getQa()
Definition: RBSystem.java:628
boolean isReal
Definition: RBSystem.java:119
int getQuL()
Definition: RBSystem.java:654
A solution field with complex values.
double residual_scaling_denom(double alpha_LB)
Specifies the residual scaling on the denominator to be used in the a posteriori error bound...
Definition: RBSystem.java:1587
Complex[][][] Z_vector
int getNBF()
Definition: RBSystem.java:605
void loadOfflineData_rbappmit(AModelManager m)
double RB_solve(int N)
Complex complex_eval_theta_q_l(int n, int q)
Definition: RBSystem.java:357
A common interface for classes providing a mesh transformation.
List< MeshTransform > transforms
Definition: RBSystem.java:220
SimulationResult getSweepSimResults()
Contains information about the logical solution fields.
double compute_residual_dual_norm(int N)
int getQl(int output_index)
TODO: if all affine_functions implement the IAffineFunctions interface, just call the getQl method of...
Definition: RBSystem.java:650
double get_SCM_lower_bound()
Definition: RBSystem.java:551