Esempio n. 1
0
import sympy as sym
import scipy as sc
from scipy import constants
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm  #Colormap
import meshio as mio
#import mshr as msr

# %%

# %%
mesh = fn.Mesh()
with fn.XDMFFile("meshing/Dmesh.xdmf") as infile:
    infile.read(mesh)
mvc = fn.MeshValueCollection("size_t", mesh, 2)
with fn.XDMFFile("meshing/Dmf.xdmf") as infile:
    infile.read(mvc, "name_to_read")
mf = fn.cpp.mesh.MeshFunctionSizet(mesh, mvc)

# %%
M = 2  #species

Poly = fn.FiniteElement('Lagrange', mesh.ufl_cell(), 2)
Multi = fn.FiniteElement('Real', mesh.ufl_cell(), 0)
ElemP = [Poly] * (M + 1)
ElemR = [Multi] * (M)
Elem = [ElemP + ElemR][0]
Mixed = fn.MixedElement(Elem)
V = fn.FunctionSpace(mesh, Mixed)
Esempio n. 2
0
def import_mesh(arg):
    """Imports a mesh file for use with CASHOCS / FEniCS.



	This function imports a mesh file that was generated by GMSH and converted to
	.xdmf with the command line function :ref:`cashocs-convert <cashocs_convert>`.
	If there are Physical quantities specified in the GMSH file, these are imported
	to the subdomains and boundaries output of this function and can also be directly
	accessed via the measures, e.g., with ``dx(1)``, ``ds(1)``, etc.

	Parameters
	----------
	arg : str or configparser.ConfigParser
		This is either a string, in which case it corresponds to the location
		of the mesh file in .xdmf file format, or a config file that
		has this path stored in its settings, under the section Mesh, as
		parameter ``mesh_file``.

	Returns
	-------
	mesh : dolfin.cpp.mesh.Mesh
		The imported (computational) mesh.
	subdomains : dolfin.cpp.mesh.MeshFunctionSizet
		A :py:class:`fenics.MeshFunction` object containing the subdomains,
		i.e., the Physical regions marked in the GMSH
		file.
	boundaries : dolfin.cpp.mesh.MeshFunctionSizet
		A MeshFunction object containing the boundaries,
		i.e., the Physical regions marked in the GMSH
		file. Can, e.g., be used to set up boundary
		conditions.
	dx : ufl.measure.Measure
		The volume measure of the mesh corresponding to
		the subdomains (i.e. GMSH Physical region indices).
	ds : ufl.measure.Measure
		The surface measure of the mesh corresponding to
		the boundaries (i.e. GMSH Physical region indices).
	dS : ufl.measure.Measure
		The interior facet measure of the mesh corresponding
		to boundaries (i.e. GMSH Physical region indices).
	"""

    start_time = time.time()
    print('Importing mesh to FEniCS')
    # Check for the file format

    if type(arg) == str:
        mesh_file = arg
        mesh_attribute = 'str'
    elif type(arg) == configparser.ConfigParser:
        mesh_attribute = 'config'
        ### overloading for remeshing
        if not arg.getboolean('Mesh', 'remesh', fallback=False):
            mesh_file = arg.get('Mesh', 'mesh_file')
        else:
            if not ('_cashocs_remesh_flag' in sys.argv):
                mesh_file = arg.get('Mesh', 'mesh_file')
            else:
                temp_dir = sys.argv[-1]
                with open(temp_dir + '/temp_dict.json', 'r') as file:
                    temp_dict = json.load(file)
                mesh_file = temp_dict['mesh_file']

    else:
        raise InputError(
            'cashocs.geometry.import_mesh', 'arg',
            'Not a valid argument for import_mesh. Has to be either a path to a mesh file (str) or a config.'
        )

    if mesh_file[-5:] == '.xdmf':
        file_string = mesh_file[:-5]
    else:
        raise InputError(
            'cashocs.geometry.import_mesh', 'arg',
            'Not a suitable mesh file format. Has to end in .xdmf.')

    mesh = fenics.Mesh()
    xdmf_file = fenics.XDMFFile(mesh.mpi_comm(), mesh_file)
    xdmf_file.read(mesh)
    xdmf_file.close()

    subdomains_mvc = fenics.MeshValueCollection('size_t', mesh,
                                                mesh.geometric_dimension())
    boundaries_mvc = fenics.MeshValueCollection('size_t', mesh,
                                                mesh.geometric_dimension() - 1)

    if os.path.isfile(file_string + '_subdomains.xdmf'):
        xdmf_subdomains = fenics.XDMFFile(mesh.mpi_comm(),
                                          file_string + '_subdomains.xdmf')
        xdmf_subdomains.read(subdomains_mvc, 'subdomains')
        xdmf_subdomains.close()
    if os.path.isfile(file_string + '_boundaries.xdmf'):
        xdmf_boundaries = fenics.XDMFFile(mesh.mpi_comm(),
                                          file_string + '_boundaries.xdmf')
        xdmf_boundaries.read(boundaries_mvc, 'boundaries')
        xdmf_boundaries.close()

    subdomains = fenics.MeshFunction('size_t', mesh, subdomains_mvc)
    boundaries = fenics.MeshFunction('size_t', mesh, boundaries_mvc)

    dx = fenics.Measure('dx', domain=mesh, subdomain_data=subdomains)
    ds = fenics.Measure('ds', domain=mesh, subdomain_data=boundaries)
    dS = fenics.Measure('dS', domain=mesh, subdomain_data=boundaries)

    end_time = time.time()
    print('Done Importing Mesh. Elapsed Time: ' +
          format(end_time - start_time, '.3e') + ' s')
    print('')

    # Add an attribute to the mesh to show with what procedure it was generated
    mesh._cashocs_generator = mesh_attribute

    return mesh, subdomains, boundaries, dx, ds, dS
def import_mesh(arg):
	"""Imports a mesh file for use with CASHOCS / FEniCS.



	This function imports a mesh file that was generated by GMSH and converted to
	.xdmf with the command line function :ref:`cashocs-convert <cashocs_convert>`.
	If there are Physical quantities specified in the GMSH file, these are imported
	to the subdomains and boundaries output of this function and can also be directly
	accessed via the measures, e.g., with ``dx(1)``, ``ds(1)``, etc.

	Parameters
	----------
	arg : str or configparser.ConfigParser
		This is either a string, in which case it corresponds to the location
		of the mesh file in .xdmf file format, or a config file that
		has this path stored in its settings, under the section Mesh, as
		parameter ``mesh_file``.

	Returns
	-------
	mesh : dolfin.cpp.mesh.Mesh
		The imported (computational) mesh.
	subdomains : dolfin.cpp.mesh.MeshFunctionSizet
		A :py:class:`fenics.MeshFunction` object containing the subdomains,
		i.e., the Physical regions marked in the GMSH
		file.
	boundaries : dolfin.cpp.mesh.MeshFunctionSizet
		A MeshFunction object containing the boundaries,
		i.e., the Physical regions marked in the GMSH
		file. Can, e.g., be used to set up boundary
		conditions.
	dx : ufl.measure.Measure
		The volume measure of the mesh corresponding to
		the subdomains (i.e. GMSH Physical region indices).
	ds : ufl.measure.Measure
		The surface measure of the mesh corresponding to
		the boundaries (i.e. GMSH Physical region indices).
	dS : ufl.measure.Measure
		The interior facet measure of the mesh corresponding
		to boundaries (i.e. GMSH Physical region indices).
	"""

	start_time = time.time()
	info('Importing mesh.')
	
	# Check for the file format
	if type(arg) == str:
		mesh_file = arg
		mesh_attribute = 'str'
	elif type(arg) == configparser.ConfigParser:
		mesh_attribute = 'config'
		### overloading for remeshing
		if not arg.getboolean('Mesh', 'remesh', fallback=False):
			mesh_file = arg.get('Mesh', 'mesh_file')
		else:
			if not ('_cashocs_remesh_flag' in sys.argv):
				mesh_file = arg.get('Mesh', 'mesh_file')
			else:
				temp_dir = sys.argv[-1]
				with open(temp_dir + '/temp_dict.json', 'r') as file:
					temp_dict = json.load(file)
				mesh_file = temp_dict['mesh_file']
				
				
	else:
		raise InputError('cashocs.geometry.import_mesh', 'arg', 'Not a valid argument for import_mesh. Has to be either a path to a mesh file (str) or a config.')

	if mesh_file[-5:] == '.xdmf':
		file_string = mesh_file[:-5]
	else:
		raise InputError('cashocs.geometry.import_mesh', 'arg', 'Not a suitable mesh file format. Has to end in .xdmf.')

	mesh = fenics.Mesh()
	xdmf_file = fenics.XDMFFile(mesh.mpi_comm(), mesh_file)
	xdmf_file.read(mesh)
	xdmf_file.close()

	subdomains_mvc = fenics.MeshValueCollection('size_t', mesh, mesh.geometric_dimension())
	boundaries_mvc = fenics.MeshValueCollection('size_t', mesh, mesh.geometric_dimension() - 1)

	if os.path.isfile(file_string + '_subdomains.xdmf'):
		xdmf_subdomains = fenics.XDMFFile(mesh.mpi_comm(), file_string + '_subdomains.xdmf')
		xdmf_subdomains.read(subdomains_mvc, 'subdomains')
		xdmf_subdomains.close()
	if os.path.isfile(file_string + '_boundaries.xdmf'):
		xdmf_boundaries = fenics.XDMFFile(mesh.mpi_comm(), file_string + '_boundaries.xdmf')
		xdmf_boundaries.read(boundaries_mvc, 'boundaries')
		xdmf_boundaries.close()

	subdomains = fenics.MeshFunction('size_t', mesh, subdomains_mvc)
	boundaries = fenics.MeshFunction('size_t', mesh, boundaries_mvc)

	dx = fenics.Measure('dx', domain=mesh, subdomain_data=subdomains)
	ds = fenics.Measure('ds', domain=mesh, subdomain_data=boundaries)
	dS = fenics.Measure('dS', domain=mesh, subdomain_data=boundaries)

	end_time = time.time()
	info('Done Importing Mesh. Elapsed Time: ' + format(end_time - start_time, '.3e') + ' s\n')

	# Add an attribute to the mesh to show with what procedure it was generated
	mesh._cashocs_generator = mesh_attribute

	# Check the mesh quality of the imported mesh in case a config file is passed
	if type(arg) == configparser.ConfigParser:
		mesh_quality_tol_lower = arg.getfloat('MeshQuality', 'tol_lower', fallback=0.0)
		mesh_quality_tol_upper =  arg.getfloat('MeshQuality', 'tol_upper', fallback=1e-15)
		
		if not mesh_quality_tol_lower < mesh_quality_tol_upper:
			raise ConfigError('MeshQuality', 'tol_lower', 'The lower remeshing tolerance has to be strictly smaller than the upper remeshing tolerance')
	
		if mesh_quality_tol_lower > 0.9*mesh_quality_tol_upper:
			warning('You are using a lower remesh tolerance (tol_lower) close to the upper one (tol_upper). This may slow down the optimization considerably.')
		
		mesh_quality_measure = arg.get('MeshQuality', 'measure', fallback='skewness')
		if not mesh_quality_measure in ['skewness', 'maximum_angle', 'radius_ratios', 'condition_number']:
			raise ConfigError('MeshQuality', 'measure', 'Has to be one of \'skewness\', \'maximum_angle\', \'condition_number\', or \'radius_ratios\'.')
	
		mesh_quality_type = arg.get('MeshQuality', 'type', fallback='min')
		if not mesh_quality_type in ['min', 'minimum', 'avg', 'average']:
			raise ConfigError('MeshQuality', 'type', 'Has to be one of \'min\', \'minimum\', \'avg\', or \'average\'.')
		
		if mesh_quality_type in ['min', 'minimum']:
			if mesh_quality_measure == 'skewness':
				current_mesh_quality = MeshQuality.min_skewness(mesh)
			elif mesh_quality_measure == 'maximum_angle':
				current_mesh_quality = MeshQuality.min_maximum_angle(mesh)
			elif mesh_quality_measure == 'radius_ratios':
				current_mesh_quality = MeshQuality.min_radius_ratios(mesh)
			elif mesh_quality_measure == 'condition_number':
				current_mesh_quality = MeshQuality.min_condition_number(mesh)
	
		else:
			if mesh_quality_measure == 'skewness':
				current_mesh_quality = MeshQuality.avg_skewness(mesh)
			elif mesh_quality_measure == 'maximum_angle':
				current_mesh_quality = MeshQuality.avg_maximum_angle(mesh)
			elif mesh_quality_measure == 'radius_ratios':
				current_mesh_quality = MeshQuality.avg_radius_ratios(mesh)
			elif mesh_quality_measure == 'condition_number':
				current_mesh_quality = MeshQuality.avg_condition_number(mesh)
		
		if not ('_cashocs_remesh_flag' in sys.argv):
			if current_mesh_quality < mesh_quality_tol_lower:
				raise InputError('cashocs.geometry.import_mesh', 'arg',
								 'The quality of the mesh file you have specified is not sufficient for evaluating the cost functional.\n'
								 'It currently is ' + format(current_mesh_quality, '.3e') + ' but has to be at least ' + format(mesh_quality_tol_lower, '.3e') + '.')
			
			if current_mesh_quality < mesh_quality_tol_upper:
				raise InputError('cashocs.geometry.import_mesh', 'arg',
								 'The quality of the mesh file you have specified is not sufficient for computing the shape gradient.\n '
								 'It currently is ' + format(current_mesh_quality, '.3e') + ' but has to be at least ' + format(mesh_quality_tol_upper, '.3e') + '.')
		
		else:
			if current_mesh_quality < mesh_quality_tol_lower:
				raise InputError('cashocs.geometry.import_mesh', 'arg',
								 'Remeshing failed.\n'
								 'The quality of the mesh file generated through remeshing is not sufficient for evaluating the cost functional.\n'
								 'It currently is ' + format(current_mesh_quality, '.3e') + ' but has to be at least ' + format(mesh_quality_tol_lower, '.3e') + '.')
			
			if current_mesh_quality < mesh_quality_tol_upper:
				raise InputError('cashocs.geometry.import_mesh', 'arg',
								 'Remeshing failed.\n'
								 'The quality of the mesh file generated through remeshing is not sufficient for computing the shape gradient.\n '
								 'It currently is ' + format(current_mesh_quality, '.3e') + ' but has to be at least ' + format(mesh_quality_tol_upper, '.3e') + '.')
		
	return mesh, subdomains, boundaries, dx, ds, dS