def getMinMax(vals, fmin=None, fmax=None): funcmin, funcmax = ngs.Vector(vals, copy=False).MinMax(True) if fmin is not None: funcmin = min(funcmin, fmin) if fmax is not None: funcmax = max(funcmax, fmax) return funcmin, funcmax
def calcSolution(k): mat = ngsolve.Matrix(k + 1, k + 1, is_complex) for i in range(k + 1): mat[:, i] = H[i][:k + 1] rs = ngsolve.Vector(k + 1, is_complex) rs[:] = beta[:k + 1] y = mat.I * rs if xstart: x.data = xstart for i in range(k + 1): x.data += y[i] * Q[i]
def updatePMinMax(pmat, pmima=None): pmima_new = [ ngs.Vector(pmat[:, i], copy=False).MinMax(ignore_inf=True) for i in range(3) ] if pmima is not None: for i in range(3): minmax = (min(pmima[i][0], pmima_new[i][0]), max(pmima[i][1], pmima_new[i][1])) pmima_new[i] = minmax return pmima_new
def arnoldi(A, Q, k): q = b.CreateVector() tmp.data = A * Q[k] q.data = pre * tmp h = ngsolve.Vector(m + 1, is_complex) h[:] = 0 for i in range(k + 1): h[i] = innerproduct(Q[i], q) q.data += (-1) * h[i] * Q[i] h[k + 1] = norm(q) if abs(h[k + 1]) < 1e-12: return h, None q *= 1. / h[k + 1].real return h, q
def getParameters(): from headless import _headless if _headless: settings = RenderingSettings() settings.initGL() else: from ngsgui.gui import gui settings = ngsgui.gui.gui.getCurrentGLWindow().glWidget._settings settings.setColormapMin(-0.3) settings.setColormapMax(1.0) settings.min = ngs.Vector([0, 0, 0]) settings.max = ngs.Vector([1, 1, 1]) settings.rotateCamera(-30, 30) settings.zoom = -50 settings.dx = -0.2 settings.dy = 0.1 settings.setLightAmbient(0.5) settings.setLightDiffuse(0.5) settings.setShowCross(False) settings.setShowVersion(False) settings.setShowColorbar(False) settings.setOrder(3) settings.setSubdivision(3) return settings
import ngsolve as ng import numpy as np W1r = ng.Matrix(3, 1) W1z = ng.Matrix(3, 1) b1 = ng.Vector(3) W2 = ng.Matrix(1, 3) b2 = ng.Vector(1) r = ng.x z = ng.y def sigmoid(x): for i in range(0, len(x)): x[i] = 1 / (1 + np.exp(-x[i])) sigmoid(W1r * r + W1z * z + b1)
def BuildRenderData(mesh, func, order=2, draw_surf=True, draw_vol=True, deformation=None, region=True, objects=[]): timer.Start() if isinstance(deformation, ngs.CoefficientFunction) and deformation.dim == 2: deformation = ngs.CoefficientFunction((deformation, 0.0)) #TODO: handle quads and non-smooth functions #TODO: subdivision d = {} d['ngsolve_version'] = ngs.__version__ d['mesh_dim'] = mesh.dim # order = order or mesh.GetCurveOrder() if (not func) and (mesh.GetCurveOrder() == 1) and (mesh.nv == len( mesh.ngmesh.Points())): order = 1 order2d = min(order, 3) order3d = min(order, 2) d['order2d'] = order2d d['order3d'] = order3d d['draw_vol'] = func and mesh.dim == 3 and draw_vol and mesh.ne > 0 d['draw_surf'] = func and draw_surf d['objects'] = [] for obj in objects: if isinstance(obj, dict): d['objects'].append(obj) else: d['objects'].append(obj._GetWebguiData()) if isinstance(deformation, bool): d['deformation'] = deformation deformation = None func0 = None func2 = None if func and func.is_complex: d['is_complex'] = True func1 = func[0].real func2 = ngs.CoefficientFunction((func[0].imag, 0.0)) d['funcdim'] = 2 elif func and func.dim > 1: func1 = func[0] func2 = ngs.CoefficientFunction( tuple(func[i] if i < func.dim else 0.0 for i in range(1, 3))) # max 3-dimensional functions d['funcdim'] = func.dim elif func: func1 = func d['funcdim'] = 1 else: # no function at all -> we are just drawing a mesh, eval mesh element index instead mats = mesh.GetMaterials() bnds = mesh.GetBoundaries() bbnds = mesh.GetBBoundaries() nmats = len(mesh.GetMaterials()) nbnds = len(mesh.GetBoundaries()) n = max(nmats, nbnds, len(bbnds)) func1 = ngs.CoefficientFunction(list(range(n))) n_regions = [0, 0, nmats, nbnds] d['mesh_regions_2d'] = n_regions[mesh.dim] d['mesh_regions_3d'] = nmats if mesh.dim == 3 else 0 d['names'] = bnds if mesh.dim == 3 else mats d['edge_names'] = bbnds if mesh.dim == 3 else bnds d['funcdim'] = 0 func0 = func1 if func0 is None: func0 = ngs.CoefficientFunction(0.0) func1 = ngs.CoefficientFunction((ngs.x, ngs.y, ngs.z, func1)) func0 = ngs.CoefficientFunction((ngs.x, ngs.y, ngs.z, func0)) if deformation is not None: func1 += ngs.CoefficientFunction((deformation, 0.0)) func0 += ngs.CoefficientFunction((deformation, 0.0)) d['show_wireframe'] = False d['show_mesh'] = False if order2d > 0: og = order2d d['show_wireframe'] = True d['show_mesh'] = True timer2.Start() timer3Bvals.Start() # transform point-values to Bernsteinbasis def Binomial(n, i): return math.factorial(n) / math.factorial(i) / math.factorial(n - i) def Bernstein(x, i, n): return Binomial(n, i) * x**i * (1 - x)**(n - i) Bvals = ngs.Matrix(og + 1, og + 1) for i in range(og + 1): for j in range(og + 1): Bvals[i, j] = Bernstein(i / og, j, og) iBvals = Bvals.I timer3Bvals.Stop() # print (Bvals) # print (iBvals) Bezier_points = [] # TODO: Quads ipts = [(i / og, 0) for i in range(og + 1)] + [ (0, i / og) for i in range(og + 1) ] + [(i / og, 1.0 - i / og) for i in range(og + 1)] ir_trig = ngs.IntegrationRule(ipts, [ 0, ] * len(ipts)) ipts = [(i / og, 0) for i in range(og + 1)] + [ (0, i / og) for i in range(og + 1) ] + [(i / og, 1.0) for i in range(og + 1)] + [(1.0, i / og) for i in range(og + 1)] ir_quad = ngs.IntegrationRule(ipts, [ 0, ] * len(ipts)) vb = [ngs.VOL, ngs.BND][mesh.dim - 2] if region and region.VB() == vb: vb = region cf = func1 if draw_surf else func0 timer2map.Start() pts = mesh.MapToAllElements( { ngs.ET.TRIG: ir_trig, ngs.ET.QUAD: ir_quad }, vb) timer2map.Stop() pmat = cf(pts) pmima = updatePMinMax(pmat) timermult.Start() pmat = pmat.reshape(-1, og + 1, 4) if False: BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1, 1)) else: BezierPnts = np.zeros((og + 1, pmat.shape[0], 4)) for i in range(4): ngsmat = ngs.Matrix(pmat[:, :, i].transpose()) BezierPnts[:, :, i] = iBvals * ngsmat timermult.Stop() timer2list.Start() for i in range(og + 1): Bezier_points.append(encodeData(BezierPnts[i])) timer2list.Stop() if func2 and draw_surf: pmat = func2(pts) pmat = pmat.reshape(-1, og + 1, 2) timermult.Start() BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1, 1)) timermult.Stop() timer2list.Start() for i in range(og + 1): Bezier_points.append(encodeData(BezierPnts[i])) timer2list.Stop() d['Bezier_points'] = Bezier_points ipts = [(i / og, 0) for i in range(og + 1)] ir_seg = ngs.IntegrationRule(ipts, [ 0, ] * len(ipts)) vb = [ngs.VOL, ngs.BND, ngs.BBND][mesh.dim - 1] if region and region.VB() == vb: vb = region pts = mesh.MapToAllElements(ir_seg, vb) pmat = func0(pts) pmima = updatePMinMax(pmat) pmat = pmat.reshape(-1, og + 1, 4) edge_data = np.tensordot(iBvals.NumPy(), pmat, axes=(1, 1)) edges = [] for i in range(og + 1): edges.append(encodeData(edge_data[i])) d['edges'] = edges timer2.Stop() timer3.Start() ndtrig = int((og + 1) * (og + 2) / 2) if og in bezier_trig_trafos.keys(): iBvals_trig = bezier_trig_trafos[og] else: def BernsteinTrig(x, y, i, j, n): return math.factorial(n)/math.factorial(i)/math.factorial(j)/math.factorial(n-i-j) \ * x**i*y**j*(1-x-y)**(n-i-j) Bvals = ngs.Matrix(ndtrig, ndtrig) ii = 0 for ix in range(og + 1): for iy in range(og + 1 - ix): jj = 0 for jx in range(og + 1): for jy in range(og + 1 - jx): Bvals[ii, jj] = BernsteinTrig(ix / og, iy / og, jx, jy, og) jj += 1 ii += 1 iBvals_trig = Bvals.I bezier_trig_trafos[og] = iBvals_trig # Bezier_points = [ [] for i in range(ndtrig) ] Bezier_points = [] ipts = [(i / og, j / og) for j in range(og + 1) for i in range(og + 1 - j)] ir_trig = ngs.IntegrationRule(ipts, [ 0, ] * len(ipts)) ipts = ([(i / og, j / og) for j in range(og + 1) for i in range(og + 1 - j)] + [(1 - i / og, 1 - j / og) for j in range(og + 1) for i in range(og + 1 - j)]) ir_quad = ngs.IntegrationRule(ipts, [ 0, ] * len(ipts)) vb = [ngs.VOL, ngs.BND][mesh.dim - 2] if region and region.VB() == vb: vb = region pts = mesh.MapToAllElements( { ngs.ET.TRIG: ir_trig, ngs.ET.QUAD: ir_quad }, vb) pmat = ngs.CoefficientFunction(func1 if draw_surf else func0)(pts) timer3minmax.Start() pmima = updatePMinMax(pmat, pmima) funcmin, funcmax = getMinMax(pmat[:, 3]) timer3minmax.Stop() pmin, pmax = [ngs.Vector(p) for p in zip(*pmima)] mesh_center = 0.5 * (pmin + pmax) mesh_radius = np.linalg.norm(pmax - pmin) / 2 pmat = pmat.reshape(-1, len(ir_trig), 4) if False: timer3multnumpy.Start() BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1, 1)) timer3multnumpy.Stop() else: timer3multngs.Start() BezierPnts = np.zeros((len(ir_trig), pmat.shape[0], 4)) for i in range(4): ngsmat = ngs.Matrix(pmat[:, :, i].transpose()) BezierPnts[:, :, i] = iBvals_trig * ngsmat timer3multngs.Stop() timer3list.Start() for i in range(ndtrig): Bezier_points.append(encodeData(BezierPnts[i])) timer3list.Stop() if func2 and draw_surf: pmat = ngs.CoefficientFunction(func2)(pts) pmat = pmat.reshape(-1, len(ir_trig), 2) funcmin, funcmax = getMinMax(pmat.flatten(), funcmin, funcmax) BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1, 1)) if og == 1: for i in range(ndtrig): Bezier_points.append(encodeData(BezierPnts[i])) else: BezierPnts = BezierPnts.transpose( (1, 0, 2)).reshape(-1, len(ir_trig) // 2, 4).transpose( (1, 0, 2)) for i in range(ndtrig // 2): Bezier_points.append(encodeData(BezierPnts[i])) d['Bezier_trig_points'] = Bezier_points d['mesh_center'] = list(mesh_center) d['mesh_radius'] = mesh_radius timer3.Stop() timer4.Start() if d['draw_vol']: p0 = [] p1 = [] p2 = [] p3 = [] values = [] tets = [] midpoint = lambda p0, p1: tuple( (0.5 * (p0[i] + p1[i]) for i in range(3))) def makeP2Tets(p1_tets): p2_tets = [] for tet in p1_tets: tet.append(midpoint(tet[0], tet[3])) tet.append(midpoint(tet[1], tet[3])) tet.append(midpoint(tet[2], tet[3])) tet.append(midpoint(tet[0], tet[1])) tet.append(midpoint(tet[0], tet[2])) tet.append(midpoint(tet[1], tet[2])) p2_tets.append(tet) return p2_tets # divide any element into tets p1_tets = {} p1_tets[ngs.ET.TET] = [[(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)]] p1_tets[ngs.ET.PYRAMID] = [[(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)], [(1, 0, 0), (0, 1, 0), (0, 0, 1), (1, 1, 0)]] p1_tets[ngs.ET.PRISM] = [[(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)], [(0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0)], [(1, 0, 1), (0, 1, 1), (1, 0, 0), (0, 0, 1)]] p1_tets[ngs.ET.HEX] = [[(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)], [(0, 1, 1), (1, 1, 1), (1, 1, 0), (1, 0, 1)], [(1, 0, 1), (0, 1, 1), (1, 0, 0), (0, 0, 1)], [(0, 1, 1), (1, 1, 0), (0, 1, 0), (1, 0, 0)], [(0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0)], [(1, 0, 1), (1, 1, 0), (0, 1, 1), (1, 0, 0)]] intrules = {} for eltype in p1_tets: points = p1_tets[eltype] if order3d > 1: points = makeP2Tets(points) intrules[eltype] = ngs.IntegrationRule(sum(points, [])) pts = mesh.MapToAllElements(intrules, ngs.VOL) pmat = func1(pts) np_per_tet = len(intrules[ngs.ET.TET]) ne = mesh.GetNE(ngs.VOL) pmat = pmat.reshape(-1, np_per_tet, 4) funcmin, funcmax = getMinMax(pmat[:, :, 3].flatten(), funcmin, funcmax) points3d = [] for i in range(np_per_tet): points3d.append(encodeData(pmat[:, i, :])) if func2: pmat = func2(pts).reshape(-1, np_per_tet // 2, 4) funcmin, funcmax = getMinMax(pmat.flatten(), funcmin, funcmax) for i in range(np_per_tet // 2): points3d.append(encodeData(pmat[:, i, :])) d['points3d'] = points3d if func: d['funcmin'] = funcmin d['funcmax'] = funcmax timer4.Stop() timer.Stop() return d
def GMRes(A, b, pre=None, freedofs=None, x=None, maxsteps=100, tol=1e-7, innerproduct=None, callback=None, restart=None, startiteration=0, printrates=True): """ Restarting preconditioned gmres solver for A*x=b. Minimizes the preconditioned residuum pre*(b-A*x) Parameters ---------- A : BaseMatrix The left hand side of the linear system. b : BaseVector The right hand side of the linear system. pre : BaseMatrix = None The preconditioner for the system. If no preconditioner is given, the freedofs of the system must be given. freedofs : BitArray = None Freedofs to solve on, only necessary if no preconditioner is given. x : BaseVector = None Startvector, if given it will be modified in the routine and returned. Will be created if not given. maxsteps : int = 100 Maximum iteration steps. tol : float = 1e-7 Tolerance to be computed to. Gmres breaks if norm(pre*(b-A*x)) < tol. innerproduct : function = None Innerproduct to be used in iteration, all orthogonalizations/norms are computed with respect to that inner product. callback : function = None If given, this function is called with the solution vector x in each step. Only for debugging purposes, since it requires the overhead of computing x in every step. restart : int = None If given, gmres is restarted with the current solution x every 'restart' steps. startiteration : int = 0 Internal value to count total number of iterations in restarted setup, no user input required here. printrates : bool = True Print norm of preconditioned residual in each step. """ if not innerproduct: innerproduct = lambda x, y: y.InnerProduct(x, conjugate=True) norm = ngsolve.Norm else: norm = lambda x: ngsolve.sqrt(innerproduct(x, x).real) # is_complex = isinstance(b.FV(), ngsolve.bla.FlatVectorC) is_complex = b.is_complex if not pre: assert freedofs pre = ngsolve.Projector(freedofs, True) n = len(b) m = maxsteps if not x: x = b.CreateVector() x[:] = 0 if callback: xstart = x.CreateVector() xstart.data = x else: xstart = None sn = ngsolve.Vector(m, is_complex) cs = ngsolve.Vector(m, is_complex) sn[:] = 0 cs[:] = 0 r = b.CreateVector() tmp = b.CreateVector() tmp.data = b - A * x r.data = pre * tmp Q = [] H = [] Q.append(b.CreateVector()) r_norm = norm(r) if abs(r_norm) < tol: return x Q[0].data = 1. / r_norm * r beta = ngsolve.Vector(m + 1, is_complex) beta[:] = 0 beta[0] = r_norm def arnoldi(A, Q, k): q = b.CreateVector() tmp.data = A * Q[k] q.data = pre * tmp h = ngsolve.Vector(m + 1, is_complex) h[:] = 0 for i in range(k + 1): h[i] = innerproduct(Q[i], q) q.data += (-1) * h[i] * Q[i] h[k + 1] = norm(q) if abs(h[k + 1]) < 1e-12: return h, None q *= 1. / h[k + 1].real return h, q def givens_rotation(v1, v2): if v2 == 0: return 1, 0 elif v1 == 0: return 0, v2 / abs(v2) else: t = ngsolve.sqrt((v1.conjugate() * v1 + v2.conjugate() * v2).real) cs = abs(v1) / t sn = v1 / abs(v1) * v2.conjugate() / t return cs, sn def apply_givens_rotation(h, cs, sn, k): for i in range(k): temp = cs[i] * h[i] + sn[i] * h[i + 1] h[i + 1] = -sn[i].conjugate() * h[i] + cs[i].conjugate() * h[i + 1] h[i] = temp cs[k], sn[k] = givens_rotation(h[k], h[k + 1]) h[k] = cs[k] * h[k] + sn[k] * h[k + 1] h[k + 1] = 0 def calcSolution(k): mat = ngsolve.Matrix(k + 1, k + 1, is_complex) for i in range(k + 1): mat[:, i] = H[i][:k + 1] rs = ngsolve.Vector(k + 1, is_complex) rs[:] = beta[:k + 1] y = mat.I * rs if xstart: x.data = xstart for i in range(k + 1): x.data += y[i] * Q[i] for k in range(m): startiteration += 1 h, q = arnoldi(A, Q, k) H.append(h) if q is None: break Q.append(q) apply_givens_rotation(h, cs, sn, k) beta[k + 1] = -sn[k].conjugate() * beta[k] beta[k] = cs[k] * beta[k] error = abs(beta[k + 1]) if printrates: print("Step", startiteration, ", error = ", error) if callback: calcSolution(k) callback(x) if error < tol: break if restart and k + 1 == restart and not (restart == maxsteps): calcSolution(k) del Q return GMRes(A, b, freedofs=freedofs, pre=pre, x=x, maxsteps=maxsteps - restart, callback=callback, tol=tol, innerproduct=innerproduct, restart=restart, startiteration=startiteration, printrates=printrates) calcSolution(k) return x
def MyGMRes(A, b, pre=None, freedofs=None, x=None, maxsteps=100, tol=1e-7, innerproduct=None, callback=None, restart=None, startiteration=0, printrates=True): """ Important Note: This version of GMRes only differs from NGSolve's current version of GMRes in that the assert statement for freedofs is now assert freedofs is not None Otherwise, everything else remains the same. """ if not innerproduct: innerproduct = lambda x, y: y.InnerProduct(x, conjugate=True) norm = ngsolve.Norm else: norm = lambda x: ngsolve.sqrt(innerproduct(x, x).real) # is_complex = isinstance(b.FV(), ngsolve.bla.FlatVectorC) is_complex = b.is_complex if not pre: assert freedofs is not None pre = ngsolve.Projector(freedofs, True) n = len(b) m = maxsteps if not x: x = b.CreateVector() x[:] = 0 if callback: xstart = x.CreateVector() xstart.data = x else: xstart = None sn = ngsolve.Vector(m, is_complex) cs = ngsolve.Vector(m, is_complex) sn[:] = 0 cs[:] = 0 r = b.CreateVector() tmp = b.CreateVector() tmp.data = b - A * x r.data = pre * tmp Q = [] H = [] Q.append(b.CreateVector()) r_norm = norm(r) if abs(r_norm) < tol: return x Q[0].data = 1. / r_norm * r beta = ngsolve.Vector(m + 1, is_complex) beta[:] = 0 beta[0] = r_norm def arnoldi(A, Q, k): q = b.CreateVector() tmp.data = A * Q[k] q.data = pre * tmp h = ngsolve.Vector(m + 1, is_complex) h[:] = 0 for i in range(k + 1): h[i] = innerproduct(Q[i], q) q.data += (-1) * h[i] * Q[i] h[k + 1] = norm(q) if abs(h[k + 1]) < 1e-12: return h, None q *= 1. / h[k + 1].real return h, q def givens_rotation(v1, v2): if v2 == 0: return 1, 0 elif v1 == 0: return 0, v2 / abs(v2) else: t = ngsolve.sqrt((v1.conjugate() * v1 + v2.conjugate() * v2).real) cs = abs(v1) / t sn = v1 / abs(v1) * v2.conjugate() / t return cs, sn def apply_givens_rotation(h, cs, sn, k): for i in range(k): temp = cs[i] * h[i] + sn[i] * h[i + 1] h[i + 1] = -sn[i].conjugate() * h[i] + cs[i].conjugate() * h[i + 1] h[i] = temp cs[k], sn[k] = givens_rotation(h[k], h[k + 1]) h[k] = cs[k] * h[k] + sn[k] * h[k + 1] h[k + 1] = 0 def calcSolution(k): mat = ngsolve.Matrix(k + 1, k + 1, is_complex) for i in range(k + 1): mat[:, i] = H[i][:k + 1] rs = ngsolve.Vector(k + 1, is_complex) rs[:] = beta[:k + 1] y = mat.I * rs if xstart: x.data = xstart for i in range(k + 1): x.data += y[i] * Q[i] for k in range(m): startiteration += 1 h, q = arnoldi(A, Q, k) H.append(h) if q is None: break Q.append(q) apply_givens_rotation(h, cs, sn, k) beta[k + 1] = -sn[k].conjugate() * beta[k] beta[k] = cs[k] * beta[k] error = abs(beta[k + 1]) if printrates: print("Step", startiteration, ", error = ", error) if callback: calcSolution(k) callback(x) if error < tol: break if restart and k + 1 == restart and not (restart == maxsteps): calcSolution(k) del Q return MyGMRes(A, b, freedofs=freedofs, pre=pre, x=x, maxsteps=maxsteps - restart, callback=callback, tol=tol, innerproduct=innerproduct, restart=restart, startiteration=startiteration, printrates=printrates) calcSolution(k) return x
def P2N(self, psc_vector, ngs_vector=None): if ngs_vector is None: ngs_vector = ngs.la.CreateParallelVector(self.pardofs) psc_loc = psc_vector.getSubVector(self.iset) ngs_vector.FV()[:] = ngs.Vector(psc_loc.getArray()) return ngs_vector