# -*- coding: utf-8 -*-# noinspection PyUnresolvedReferencesr""".. _docs-space:Space=====Having abstract meshes, you can define abstract finite dimensional function spaces on them.To do so, we first need to set the target mesh by calling>>> ph.space.set_mesh(mesh)Note that if there is only one mesh defined, above command can be omitted.Then, to define a finite dimensional function space on this mesh, call function ``ph.space.new``, .. autofunction:: src.spaces.main.newSo far, we have implemented the following spaces... admonition:: Implemented spaces +-------------------------+-----------------+------------------------------+-------------------------------------+ | **description** |**abbr.** | **arg** | **kwarg** | +-------------------------+-----------------+------------------------------+-------------------------------------+ | scalar-valued form | ``'Lambda'`` | ``k`` : int. | ``orientation``: | | space | | It is a :math:`k`-form | {``'inner'``, ``'outer'``}. | | | | space. | The orientation of the form space.| | | | | The default orientation is | | | | | ``'outer'``. | | | | | | +-------------------------+-----------------+------------------------------+-------------------------------------+For example, to make spaces of outer orientated 1-forms and 2-forms, do>>> Out1 = ph.space.new('Lambda', 1, orientation='outer')>>> Out2 = ph.space.new('Lambda', 2, orientation='outer')And we can list all existing spaces by calling ``ph.list_spaces`` method,>>> ph.list_spaces() # doctest: +ELLIPSISImplemented spaces:..... automodule:: src.spaces.base :undoc-members:"""importsysif'./'notinsys.path:sys.path.append('./')fromimportlibimportimport_module_config={'current_mesh':'',}_mesh_set=dict()_space_set=dict()_sep=' ->- '# whenever new space is implemented, add it below._implemented_spaces={# indicator: (class path , class name , description , parameters),'Lambda':('src.spaces.continuous.Lambda','ScalarValuedFormSpace','scalar valued k-form space',['k',]),'bundle':('src.spaces.continuous.bundle','BundleValuedFormSpace','bundle valued k-form space',['k',]),'bundle-diagonal':('src.spaces.continuous.bundle_diagonal','DiagonalBundleValuedFormSpace','diagonal bundle valued k-form space',['k',]),}
[docs]defnew(abbr,*args,mesh=None,**kwargs):"""Generate a spaces on the mesh. Parameters ---------- abbr : str The abbr. of the space. args : The arguments to be sent to the space. mesh : {:class:`Mesh`, None}, optional We want to generate space on this mesh. If it is ``None``, we use the current target mesh. The default value is ``None``. kwargs : The keyword arguments to be sent to the space. Returns ------- space : The finite dimensional space. """if_config['current_mesh']==''andmeshisNone:raiseException(f"pls set a mesh firstly by using 'space.set_mesh' or specify 'mesh'.")else:passifisinstance(abbr,str):# make only 1 spacepasselse:raiseNotImplementedError()mesh_sr=_config['current_mesh']ifmeshisNone:mesh=_mesh_set[mesh_sr]else:# noinspection PyUnresolvedReferencesmesh_sr=mesh._sym_reprifmesh_srin_mesh_set:passelse:_mesh_set[mesh_sr]=mesh_space_set[mesh_sr]=dict()current_spaces=_space_set[mesh_sr]assertabbrin_implemented_spaces, \
f"space abbr.={abbr} not implemented. do 'ph.space.list_()' to see all implemented spaces."space_class_path,space_class_name=_implemented_spaces[abbr][0:2]space_class=getattr(import_module(space_class_path),space_class_name)space=space_class(mesh,*args,**kwargs)srp=space._sym_repr# do not use __repr__()ifsrpincurrent_spaces:passelse:current_spaces[srp]=spacespace=current_spaces[srp]returnspace
__all__=['_VarSetting_mass_matrix',#'_VarSetting_trace_matrix',# trace matrix'_VarSetting_d_matrix',#'_VarSetting_d_matrix_transpose',#'_VarSetting_pi_matrix','_VarSetting_star_matrix',# Hodge matrix'_VarSetting_dp_matrix',# <A|B>'_VarSetting_boundary_dp_vector',#'_VarSetting_astA_convect_astB_ip_tC',# (*A .V *B, @C), AB are known, vector.'_VarSetting_astA_x_astB_ip_tC',#'_VarSetting_astA_x_B_ip_tC',#'_VarSetting_A_x_astB_ip_tC',#'_VarSetting_A_x_B_ip_C',# nonlinear'_VarSetting_astA_x_astB__dp__tC',# vector <*A x *B | @C>, AB are known'_VarSetting_astA_x_B__dp__tC','_VarSetting_A_x_astB__dp__tC','_VarSetting_astA_x_astB__ip__astC_x_tD',# vector (*A x *B, *C x @D), ABC known, D test.'_VarSetting_A_x_astB__ip__astC_x_tD',# matrix (A x *B, *C x @D), BC known, D test.'_VarSetting_astA_x_astB__dp__astC_x_tD',# vector <*A x *B | *C x @D>, ABC known, D test.# bundle valued forms ---------------------------------------------------------'_VarSetting_dastA_astA_tp_tC',#'_VarSetting_dastA_tB_tp_astA','_VarSetting_dtA_astB_tp_astB','_VarSetting_dA_B_tp_C__1Known','_VarSetting_dA_B_tp_C__2Known','_VarSetting_dA_B_tp_C',# nonlinear'_VarSetting_A_B_tp_C__1Known','_VarSetting_A_B_tp_C__2Known','_VarSetting_A_B_tp_C',# nonlinear'_VarSetting_IP_matrix_db_bf',#'_VarSetting_IP_matrix_bf_db',## '_VarSetting_A_x_astB_ip_dC', # (A x B, dC)# '_VarSetting_astA_x_B_ip_dC', # (A x B, dC)# '_VarSetting_astA_x_astB_ip_dC', # (A x B, dC)]# ------ basic -----------------------------------------------------------------------------------_VarSetting_mass_matrix=[r"\mathsf{M}",_sep.join(["Mass:Mat","{space_pure_lin_repr}","{d0}","{d1}"]),]_VarSetting_trace_matrix=[r"\mathbb{T}",_sep.join(["Trace:Mat","{space_pure_lin_repr}","{degree}"]),]# _VarSetting_trace_mass_matrix = [# r"\mathbb{M}",# _sep.join(["Trace:Mat", "{space_pure_lin_repr}", "{degree}"]),# ]_VarSetting_d_matrix=[r"\mathsf{D}",_sep.join(["d:Mat","{space_pure_lin_repr}","{d}"]),]_VarSetting_d_matrix_transpose=[r"\mathbb{D}",_sep.join(["d:T:Mat","{space_pure_lin_repr}","{d}"]),]_VarSetting_pi_matrix=[r"\mathsf{P}",_sep.join(["d:P:Mat","{space_pure_lin_repr_from}","{space_pure_lin_repr_to}","{d_from}","{d_to}"# degree_from, degree_to]),]_VarSetting_star_matrix=[r"\mathsf{H}",_sep.join(["Hodge:Mat","{space_pure_lin_repr_from}","{space_pure_lin_repr_to}","{d_from}","{d_to}"# degree_from, degree_to]),]_VarSetting_dp_matrix=[# <A|B> or <B|A> : 0 refers to the axis-0 space.r"\mathsf{W}",_sep.join(["Wedge:Mat","{s0}","{s1}","{d0}","{d1}"]),]# Natural bc -------------------------------------------------------------------------------------_VarSetting_boundary_dp_vector=[# once we know f0, we can find the correct basis functions it wedged withr"\boldsymbol{b}",_sep.join(["BoundaryDP:Vec","trStar[{f0}]","tr[{f1}]"]),# <tr star bf0 | tr f1>.]# (A .V B, C) -------------------------------------------------------------------------------------_VarSetting_astA_convect_astB_ip_tC=[r"\mathsf{V}_{\left({A} \cdot\nabla {B}, \mathsf{t}\right)}^{\left[\mathsf{t}\right]}",_sep.join(["*convect*_ip","[{A}]","[{B}]","[{C}]"]),]# (w x u, u) --------------------------------------------------------------------------------------_VarSetting_astA_x_astB_ip_tC=[r"\mathsf{V}_{\left({A}\times{B}, \mathsf{t}\right)}^{\left[\mathsf{t}\right]}",_sep.join(["c_ip","[{A}]","[{B}]","[{C}]"]),]_VarSetting_astA_x_B_ip_tC=[r"\mathsf{M}_{\left({A}\times \circ, \mathsf{t}\right)}^{\left[\mathsf{t},\circ\right]}",_sep.join(["X_ip","[{A}]","[{B}]","[{C}]"]),]_VarSetting_A_x_astB_ip_tC=[r"\mathsf{M}_{\left(\circ\times {B}, \mathsf{t}\right)}^{\left[\mathsf{t},\circ\right]}",_sep.join(["_Xip","[{A}]","[{B}]","[{C}]"]),]_VarSetting_A_x_B_ip_C=[r"\mathsf{X}",_sep.join(["_X_:","[{A}]","[{B}]","[{C}]"]),]# --------------- <A x B | C> --------------------------------------------------------------------_VarSetting_astA_x_astB__dp__tC=[# <*A x *B | @D>r"\mathsf{V}_{\left\langle\left.{A}\times {B} \right| \mathsf{t}\right\rangle}^{\left[\mathsf{t}\right]}",_sep.join(["<*x*|C>","[{A}]","[{B}]","[{C}]"])]_VarSetting_astA_x_B__dp__tC=[# <*A x B | @D>r"\mathsf{M}_{\left\langle\left.{A}\times \circ \right| \mathsf{t}\right\rangle}^{\left[\mathsf{t},\circ\right]}",_sep.join(["<*xB|C>","[{A}]","[{B}]","[{C}]"])]_VarSetting_A_x_astB__dp__tC=[# <A x *B | @D>r"\mathsf{M}_{\left\langle\left. \circ \times {B} \right| \mathsf{t}\right\rangle}^{\left[\mathsf{t},\circ\right]}",_sep.join(["<Ax*|C>","[{A}]","[{B}]","[{C}]"])]# --------------- (A x B, C x D) ----------------------------------------------------_VarSetting_astA_x_astB__ip__astC_x_tD=[# (*A x *B, *C x @D)r"\mathsf{V}_{\left({A} \times {B}, {C} \times \mathsf{t}\right)}^{\left[\mathsf{t}\right]}",_sep.join(["(*x*,*xD)","[{A}]","[{B}]","[{C}]","[{D}]"]),]_VarSetting_A_x_astB__ip__astC_x_tD=[# (A x *B, *C x @D)r"\mathsf{M}_{\left(\circ \times {B}, {C} \times \mathsf{t}\right)}^{\left[\mathsf{t},\circ\right]}",_sep.join(["(Ax*,*xD)","[{A}]","[{B}]","[{C}]","[{D}]"]),]# --------------- <A x B | C x D> ----------------------------------------------------_VarSetting_astA_x_astB__dp__astC_x_tD=[# <*A x *B | *C x @D>r"\mathsf{V}_{\left\langle\left.{A}\times {B} \right| {C}\times \mathsf{t}\right\rangle}^{\left[\mathsf{t}\right]}",_sep.join(["<*x*|*xD>","[{A}]","[{B}]","[{C}]","[{D}]"]),]# -----(dA, B otimes C) --------------------------------------------------------------------------_VarSetting_dastA_astA_tp_tC=[r"\left<\mathsf{d\cdot,\cdot\otimes\_}\right>",_sep.join(["d*A--*A-tp-tC","[{A}]","[{C}]"]),]_VarSetting_dastA_tB_tp_astA=[r"\left<\mathsf{d\cdot,\_\otimes\cdot}\right>",_sep.join(["d*A--tB-tp-*A","[{A}]","[{B}]"]),]_VarSetting_dtA_astB_tp_astB=[r"\left<\mathsf{d\_,\cdot\otimes\cdot}\right>",_sep.join(["dtA--*B-tp-*B","[{A}]","[{B}]"]),]_VarSetting_dA_B_tp_C__1Known=[# A, B, C are different; and it must have a test formr"\left<\mathsf{d\_,\_\otimes\_}\right>",_sep.join(["dA--B-tp-C:1:Known","[{A}]","[{B}]","[{C}]","[{K}]","[{T}]","[{U}]"]),]_VarSetting_dA_B_tp_C__2Known=[# A, B, C are different; two of them are known, and the rest one is the test formr"\left<\mathsf{d\_,\_\otimes\_}\right>",_sep.join(["dA--B-tp-C:2:Known","[{A}]","[{B}]","[{C}]","[{K1}]","[{K2}]","[{T}]"]),]_VarSetting_dA_B_tp_C=[# A, B, C are different; # nonlinearr"\left<\mathsf{d\cdot,\cdot\otimes\cdot}\right>",_sep.join(["dA--B-tp-C","[{A}]","[{B}]","[{C}]"]),]# (A, B otimes C) -------------------------------------------------------_VarSetting_A_B_tp_C__1Known=[# A, B, C are different; and it must have a test formr"\left<\mathsf{\_,\_\otimes\_}\right>",_sep.join(["A--B-tp-C:1:Known","[{A}]","[{B}]","[{C}]","[{K}]","[{T}]","[{U}]"]),]_VarSetting_A_B_tp_C__2Known=[# A, B, C are different; two of them are known, and the rest one is the test formr"\left<\mathsf{\_,\_\otimes\_}\right>",_sep.join(["A--B-tp-C:2:Known","[{A}]","[{B}]","[{C}]","[{K1}]","[{K2}]","[{T}]"]),]_VarSetting_A_B_tp_C=[# A, B, C are different; # nonlinearr"\left<\mathsf{\cdot,\cdot\otimes\cdot}\right>",_sep.join(["A--B-tp-C","[{A}]","[{B}]","[{C}]"]),]# (bundle form, special diagonal bundle form)------------------------------------------------------_VarSetting_IP_matrix_db_bf=[r"\mathbb{M}_{\mathcal{S}}",_sep.join(["db-M-bf","{db_space_pure_lin_repr}","{bf_space_pure_lin_repr}","{degree_db}","{degree_bf}"]),]_VarSetting_IP_matrix_bf_db=[r"\mathbb{M}^{\mathsf{T}}_{\mathcal{S}}",_sep.join(["bf-M-db","{bf_space_pure_lin_repr}","{db_space_pure_lin_repr}","{degree_bf}","{degree_db}"]),]_default_space_degree_repr=':D-'_degree_cache={}def_degree_str_maker(degree):""""""str_degree=degree.__class__.__name__+str(degree)_degree_cache[str_degree]=degreereturnstr_degreedef_str_degree_parser(str_degree):""""""return_degree_cache[str_degree]defset_mesh(mesh):""""""assertmesh.__class__.__name__=='Mesh', \
f"I need a Mesh instance."sr=mesh._sym_reprifsrin_mesh_set:passelse:_mesh_set[sr]=mesh_space_set[sr]=dict()_config['current_mesh']=srdef_list_spaces():""""""fromsrc.configimportRANK,MASTER_RANKifRANK!=MASTER_RANK:returnelse:passprint('Implemented spaces:')print('{:>15} - {}'.format('abbreviation','description'))forabbrin_implemented_spaces:description=_implemented_spaces[abbr][2]print('{:>15} | {}'.format(abbr,description))print('\n Existing spaces:')formeshin_space_set:spaces=_space_set[mesh]print('{:>15}{}'.format('On mesh',mesh))fori,srinenumerate(spaces):space=spaces[sr]print('{:>15}: {}'.format(i,space._sym_repr))deffinite(degree,mesh=None,spaces=None):""" Parameters ---------- degree mesh spaces Returns ------- """ifmeshisNone:# do it for all spaces on all meshes.formesh_srin_mesh_set:mesh=_mesh_set[mesh_sr]finite(degree,mesh=mesh,spaces=spaces)returnelse:assertmesh.__class__.__name__=='Mesh',f"Mesh = {mesh} is not a Mesh object."mesh_sr=mesh._sym_reprall_current_spaces=_space_set[mesh_sr]ifspacesisNone:spaces=all_current_spaces.values()else:ifnotisinstance(spaces,(list,tuple)):spaces=[spaces,]else:passforspinspaces:assertsp._sym_reprinall_current_spaces,f"space: {sp} is not a space in current mesh {mesh}."forspaceinspaces:space.finite.specify_all(degree)