postprocess.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. """
  2. A module for postprocessing the numerical results from HDPG1d solver.
  3. """
  4. import matplotlib.pyplot as plt
  5. import numpy as np
  6. class utils(object):
  7. exactNumEle = 300
  8. exactBasisFuncs = 5
  9. def __init__(self, solution):
  10. self.solution = solution
  11. self.numEle = self.exactNumEle
  12. self.exactSoln = self.solveExact()
  13. def solveExact(self):
  14. self.solution.coeff.numEle = self.exactNumEle
  15. self.solution.coeff.pOrder = self.exactBasisFuncs - 1
  16. self.solution.mesh = np.linspace(0, 1, self.exactNumEle + 1)
  17. # approximate the exact solution for general problems
  18. self.solution.solvePrimal()
  19. exactSoln = self.solution.separateSoln(self.solution.primalSoln)[0][
  20. self.exactNumEle * self.exactBasisFuncs - 1]
  21. # for the reaction diffusion test problem, we know the exact solution
  22. # self.exactSol = np.sqrt(self.solution.coeff.diffusion)
  23. return exactSoln
  24. def errorL2(self):
  25. errorL2 = 0.
  26. numEle = self.solution.coeff.numEle
  27. self.solution.numEle = numEle
  28. numBasisFuncs = self.solution.coeff.pOrder + 1
  29. # solve on the uniform mesh
  30. self.solution.mesh = np.linspace(0, 1, numEle + 1)
  31. self.solution.solvePrimal()
  32. gradState, _ = self.solution.separateSoln(self.solution.primalSoln)
  33. errorL2 = np.abs(
  34. gradState[numBasisFuncs * numEle - 1] - self.exactSoln)
  35. return errorL2
  36. def uniConv(self):
  37. numBasisFuncs = np.arange(
  38. self.solution.numBasisFuncs, self.solution.numBasisFuncs + 1)
  39. numEle = 2**np.arange(1, 9)
  40. uniError = np.zeros((numEle.size, numBasisFuncs.size))
  41. for i in range(numBasisFuncs.size):
  42. self.solution.coeff.pOrder = numBasisFuncs[i] - 1
  43. for j, n in enumerate(numEle):
  44. self.solution.coeff.numEle = n
  45. uniError[j, i] = self.errorL2()
  46. return numEle, uniError
  47. def convHistory(self):
  48. """Plot the uniform and adaptive convergence history"""
  49. print("Please note that the error is calculated using {} "
  50. "elements with polynomial order {}."
  51. .format(self.exactNumEle, self.exactBasisFuncs))
  52. plt.figure(2)
  53. trueErrorList = self.solution.trueErrorList
  54. trueErrorList[1] = np.abs(trueErrorList[1] - self.exactSoln)
  55. estErrorList = self.solution.estErrorList
  56. plt.loglog(trueErrorList[0],
  57. trueErrorList[1], '-ro')
  58. numEle, errorL2 = self.uniConv()
  59. plt.loglog(numEle, errorL2, '-o')
  60. plt.loglog(estErrorList[0],
  61. estErrorList[1], '--', color='#1f77b4')
  62. plt.xlabel('Number of elements', fontsize=17)
  63. plt.ylabel('Error', fontsize=17)
  64. plt.grid()
  65. plt.legend(('Adaptive', 'Uniform', 'Estimator'), loc=3, fontsize=15)
  66. plt.show()