From 22ef1ebe47e9675b5e916ab3b185e891acd41896 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Mon, 1 Jul 2019 00:03:25 +0200 Subject: [PATCH] FEM: code forating, solver fenics tools, get rid of not needed indent --- src/Mod/Fem/femsolver/fenics/fenics_tools.py | 431 ++++++++++--------- 1 file changed, 218 insertions(+), 213 deletions(-) diff --git a/src/Mod/Fem/femsolver/fenics/fenics_tools.py b/src/Mod/Fem/femsolver/fenics/fenics_tools.py index f71ce29fea..7cf9135371 100644 --- a/src/Mod/Fem/femsolver/fenics/fenics_tools.py +++ b/src/Mod/Fem/femsolver/fenics/fenics_tools.py @@ -27,250 +27,255 @@ __url__ = "http://www.freecadweb.org" # \ingroup FEM import FreeCAD +import numpy as np try: import fenics except ImportError: - FreeCAD.Console.PrintError("No Fenics modules found, please install them.") -else: - import numpy as np + FreeCAD.Console.PrintError("No Fenics modules found, please install them.\n") +raise Exception("No Fenics modules found, please install them.\n") - class XDMFReader(object): + +class XDMFReader(object): + """ + Reads XDMF file and provides unified interface for returning + cell functions or facet functions. + """ + def __init__(self, xdmffilename): """ - Reads XDMF file and provides unified interface for returning - cell functions or facet functions. + Sets filename and sets mesh instance to None. """ - def __init__(self, xdmffilename): - """ - Sets filename and sets mesh instance to None. - """ - self.xdmffilename = xdmffilename - self.mesh = None + self.xdmffilename = xdmffilename + self.mesh = None - def resetMesh(self): - """ - Resets mesh instance to None. - """ - self.mesh = None + def resetMesh(self): + """ + Resets mesh instance to None. + """ + self.mesh = None - def readMesh(self): - """ - If mesh instance is None, read mesh instance from file denoted - by filename property. - """ - # TODO: implement mesh read in for open file - if self.mesh is None: - xdmffile = fenics.XDMFFile(self.xdmffilename) - self.mesh = fenics.Mesh() - xdmffile.read(self.mesh) - xdmffile.close() + def readMesh(self): + """ + If mesh instance is None, read mesh instance from file denoted + by filename property. + """ + # TODO: implement mesh read in for open file + if self.mesh is None: + xdmffile = fenics.XDMFFile(self.xdmffilename) + self.mesh = fenics.Mesh() + xdmffile.read(self.mesh) + xdmffile.close() - def readCellExpression( - self, + def readCellExpression( + self, + group_value_dict, + value_type="scalar", + overlap=lambda x: x[0], + *args, + **kwargs + ): + """ + Reads cell expression and returns it. + """ + value_type_dictionary = { + "scalar": ScalarCellExpressionFromXDMF, + "vector2d": Vector2DCellExpressionFromXDMF, + "vector3d": Vector3DCellExpressionFromXDMF} + + self.readMesh() + xdmffile = fenics.XDMFFile(self.xdmffilename) + cf = value_type_dictionary[value_type.lower()]( group_value_dict, - value_type="scalar", - overlap=lambda x: x[0], - *args, - **kwargs - ): - """ - Reads cell expression and returns it. - """ - value_type_dictionary = { - "scalar": ScalarCellExpressionFromXDMF, - "vector2d": Vector2DCellExpressionFromXDMF, - "vector3d": Vector3DCellExpressionFromXDMF} - - self.readMesh() - xdmffile = fenics.XDMFFile(self.xdmffilename) - cf = value_type_dictionary[value_type.lower()]( - group_value_dict, - overlap=overlap, - *args, **kwargs + overlap=overlap, + *args, **kwargs + ) + cf.init() + for (key, value) in cf.group_value_dict.items(): + cf.markers[key] = fenics.MeshFunction( + "size_t", + self.mesh, + self.mesh.topology().dim() ) - cf.init() - for (key, value) in cf.group_value_dict.items(): - cf.markers[key] = fenics.MeshFunction( - "size_t", - self.mesh, - self.mesh.topology().dim() - ) - xdmffile.read(cf.markers[key], key) - cf.dx[key] = fenics.Measure( - "dx", - domain=self.mesh, - subdomain_data=cf.markers[key] - ) - xdmffile.close() - return cf + xdmffile.read(cf.markers[key], key) + cf.dx[key] = fenics.Measure( + "dx", + domain=self.mesh, + subdomain_data=cf.markers[key] + ) + xdmffile.close() + return cf - def readFacetFunction(self, group_value_dict, *args, **kwargs): - """ - Reads facet function and returns it. - """ - self.readMesh() - xdmffile = fenics.XDMFFile(self.xdmffilename) - ff = FacetFunctionFromXDMF(group_value_dict, *args, **kwargs) - ff.init() - for (key, value) in ff.group_value_dict.items(): - ff.markers[key] = fenics.MeshFunction( - "size_t", - self.mesh, - self.mesh.topology().dim() - 1 - ) - xdmffile.read(ff.markers[key], key) - ff.marked[key] = value.get("marked", 1) - ff.ds[key] = fenics.Measure( - "ds", - domain=self.mesh, - subdomain_data=ff.markers[key] - ) - ff.bcs[key] = value - xdmffile.close() - return ff + def readFacetFunction(self, group_value_dict, *args, **kwargs): + """ + Reads facet function and returns it. + """ + self.readMesh() + xdmffile = fenics.XDMFFile(self.xdmffilename) + ff = FacetFunctionFromXDMF(group_value_dict, *args, **kwargs) + ff.init() + for (key, value) in ff.group_value_dict.items(): + ff.markers[key] = fenics.MeshFunction( + "size_t", + self.mesh, + self.mesh.topology().dim() - 1 + ) + xdmffile.read(ff.markers[key], key) + ff.marked[key] = value.get("marked", 1) + ff.ds[key] = fenics.Measure( + "ds", + domain=self.mesh, + subdomain_data=ff.markers[key] + ) + ff.bcs[key] = value + xdmffile.close() + return ff - class CellExpressionFromXDMF(object): - """ - Creates cell function expression from XDMF file. - """ - def __init__( + +class CellExpressionFromXDMF(object): + """ + Creates cell function expression from XDMF file. + """ + def __init__( + self, group_value_dict, + default=lambda x: 0., + check_marked=(lambda x: x == 1), + overlap=lambda x: x[0], + **kwargs + ): + self.init() + self.group_value_dict = group_value_dict + self.check_marked = check_marked + self.overlap = overlap + self.default = default + + def init(self): + self.markers = {} + self.dx = {} + + def assign_values(self, values, to_assign): + values[:] = to_assign + + def eval_cell_backend(self, values, x, cell): + + values_list = [ + func(x) for (key, func) in self.group_value_dict.items() + if self.check_marked(self.markers[key][cell.index]) + ] + return_value = self.overlap(values_list) + + if values_list: + self.assign_values(values, return_value) + else: + self.assign_values(values, self.default(x)) + + # TODO: python classes much slower than JIT compilation + + +# *********************************** +# * Sub classes due to value_shape method which is not of dynamical return type +# * Also the assignment of values is to be done by reference. Therefore it has to be +# * overloaded. +# *********************************** +class ScalarCellExpressionFromXDMF(fenics.Expression, CellExpressionFromXDMF): + + def __init__( + self, + group_value_dict, + default=lambda x: 0., + check_marked=(lambda x: x == 1), + overlap=lambda x: x[0], + **kwargs + ): + CellExpressionFromXDMF.__init__( self, group_value_dict, - default=lambda x: 0., - check_marked=(lambda x: x == 1), - overlap=lambda x: x[0], - **kwargs - ): - self.init() - self.group_value_dict = group_value_dict - self.check_marked = check_marked - self.overlap = overlap - self.default = default + default=default, + check_marked=check_marked, + overlap=overlap + ) - def init(self): - self.markers = {} - self.dx = {} + def eval_cell(self, values, x, cell): + self.eval_cell_backend(values, x, cell) - def assign_values(self, values, to_assign): - values[:] = to_assign + def value_shape(self): + return () - def eval_cell_backend(self, values, x, cell): - values_list = [ - func(x) for (key, func) in self.group_value_dict.items() - if self.check_marked(self.markers[key][cell.index]) - ] - return_value = self.overlap(values_list) +class Vector3DCellExpressionFromXDMF(fenics.Expression, CellExpressionFromXDMF): - if values_list: - self.assign_values(values, return_value) - else: - self.assign_values(values, self.default(x)) + def __init__( + self, + group_value_dict, + default=lambda x: np.zeros((3,)), + check_marked=(lambda x: x == 1), + overlap=lambda x: x[0], **kwargs + ): + CellExpressionFromXDMF.__init__( + self, group_value_dict, + default=default, + check_marked=check_marked, + overlap=overlap + ) - # TODO: python classes much slower than JIT compilation + def eval_cell(self, values, x, cell): + self.eval_cell_backend(values, x, cell) - # *********************************** - # * Sub classes due to value_shape method which is not of dynamical return type - # * Also the assignment of values is to be done by reference. Therefore it has to be - # * overloaded. - # *********************************** + def value_shape(self): + return (3,) - class ScalarCellExpressionFromXDMF(fenics.Expression, CellExpressionFromXDMF): - def __init__( +class Vector2DCellExpressionFromXDMF(fenics.Expression, CellExpressionFromXDMF): + + def __init__( + self, + group_value_dict, + default=lambda x: np.zeros((2,)), + check_marked=(lambda x: x == 1), + overlap=lambda x: x[0], + **kwargs + ): + CellExpressionFromXDMF.__init__( self, group_value_dict, - default=lambda x: 0., - check_marked=(lambda x: x == 1), - overlap=lambda x: x[0], - **kwargs - ): - CellExpressionFromXDMF.__init__( - self, group_value_dict, - default=default, - check_marked=check_marked, - overlap=overlap - ) + default=default, + check_marked=check_marked, + overlap=overlap + ) - def eval_cell(self, values, x, cell): - self.eval_cell_backend(values, x, cell) + def eval_cell(self, values, x, cell): + self.eval_cell_backend(values, x, cell) - def value_shape(self): - return () + def value_shape(self): + return (2,) - class Vector3DCellExpressionFromXDMF(fenics.Expression, CellExpressionFromXDMF): - def __init__( - self, - group_value_dict, - default=lambda x: np.zeros((3,)), - check_marked=(lambda x: x == 1), - overlap=lambda x: x[0], **kwargs - ): - CellExpressionFromXDMF.__init__( - self, group_value_dict, - default=default, - check_marked=check_marked, - overlap=overlap - ) +class FacetFunctionFromXDMF(object): + """ + Creates facet function from XDMF file. + """ + def __init__(self, group_value_dict, *args, **kwargs): + self.group_value_dict = group_value_dict + self.init() - def eval_cell(self, values, x, cell): - self.eval_cell_backend(values, x, cell) + def init(self): + self.markers = {} + self.marked = {} + self.ds = {} + self.bcs = {} - def value_shape(self): - return (3,) - - class Vector2DCellExpressionFromXDMF(fenics.Expression, CellExpressionFromXDMF): - - def __init__( - self, - group_value_dict, - default=lambda x: np.zeros((2,)), - check_marked=(lambda x: x == 1), - overlap=lambda x: x[0], - **kwargs - ): - CellExpressionFromXDMF.__init__( - self, - group_value_dict, - default=default, - check_marked=check_marked, - overlap=overlap - ) - - def eval_cell(self, values, x, cell): - self.eval_cell_backend(values, x, cell) - - def value_shape(self): - return (2,) - - class FacetFunctionFromXDMF(object): - """ - Creates facet function from XDMF file. - """ - def __init__(self, group_value_dict, *args, **kwargs): - self.group_value_dict = group_value_dict - self.init() - - def init(self): - self.markers = {} - self.marked = {} - self.ds = {} - self.bcs = {} - - def getDirichletBCs(self, vectorspace, *args, **kwargs): - dbcs = [] - for (dict_key, dict_value) in self.bcs.items(): - if dict_value["type"] == "Dirichlet": - bc = fenics.DirichletBC( - vectorspace, - dict_value["value"], - self.markers[dict_key], - dict_value.get("marked", 1), - *args, **kwargs - ) - dbcs.append(bc) - return dbcs - # TODO: write some functions to return integrals for Neumann and Robin - # boundary conditions for the general case (i.e. vector, tensor) + def getDirichletBCs(self, vectorspace, *args, **kwargs): + dbcs = [] + for (dict_key, dict_value) in self.bcs.items(): + if dict_value["type"] == "Dirichlet": + bc = fenics.DirichletBC( + vectorspace, + dict_value["value"], + self.markers[dict_key], + dict_value.get("marked", 1), + *args, **kwargs + ) + dbcs.append(bc) + return dbcs + # TODO: write some functions to return integrals for Neumann and Robin + # boundary conditions for the general case (i.e. vector, tensor) ## @}