<commit_before>from sfepy.base.base import *
try:
    from sfepy.terms.extmods import terms
except (ImportError, AttributeError):
    from sfepy.base.base import output
    msg = 'sfepy extension modules are not compiled!\ntype "make"'
    raise ImportError( msg )
from sfepy.base.la import split_range, combine
#from sfepy.base.ioutils import read_cache_data, write_cache_data

_match_var = re.compile( '^virtual$|^state(_[_a-zA-Z0-9]+)?$'\
                        + '|^parameter(_[_a-zA-Z0-9]+)?$' ).match
_match_state = re.compile( '^state(_[_a-zA-Z0-9]+)?$' ).match
_match_parameter = re.compile( '^parameter(_[_a-zA-Z0-9]+)?$' ).match
_match_material = re.compile( '^material(_[_a-zA-Z0-9]+)?$' ).match
_match_material_root = re.compile( '(.+)\.(.*)' ).match

def vector_chunk_generator( total_size, chunk_size, shape_in,
                            zero = False, set_shape = True, dtype = nm.float64 ):
    if not chunk_size:
        chunk_size = total_size
    shape = list( shape_in )

    sizes = split_range( total_size, chunk_size )
    ii = nm.array( 0, dtype = nm.int32 )
    for size in sizes:
        chunk = nm.arange( size, dtype = nm.int32 ) + ii
        if set_shape:
            shape[0] = size
        if zero:
            out = nm.zeros( shape, dtype = dtype )
        else:
            out = nm.empty( shape, dtype = dtype )
        yield out, chunk
        ii += size

##
# 22.01.2006, c
class CharacteristicFunction( Struct ):
    ##
    # c: 22.01.2006, r: 09.05.2008
    def __init__( self, region ):
        self.igs = region.igs
        self.region = region
        self.i_current = None
        self.local_chunk = None
        self.ig = None

    def __call__(self, chunk_size, shape_in, zero=False, set_shape=True,
                  ret_local_chunk=False, dtype=nm.float64):
        els = self.region.cells[self.ig]
        for out, chunk in vector_chunk_generator( els.shape[0], chunk_size,
                                                  shape_in, zero, set_shape,
                                                  dtype ):
            self.local_chunk = chunk

            if ret_local_chunk:
                yield out, chunk
            else:
                yield out, els[chunk]
                
        self.local_chunk = None

    ##
    # 11.08.2006, c
    # 27.02.2007
    def set_current_group( self, ig ):
        self.ig = ig
        
    ##
    # 05.09.2006, c
    def get_local_chunk( self ):
        return self.local_chunk

##
# 24.07.2006, c
class Terms( Container ):

    ##
    # 24.07.2006, c
    def classify_args( self, variables ):
        for term in self:
            term.classify_args( variables )
            
    ##
    # 24.07.2006, c
    # 02.08.2006
    def get_variable_names( self ):
        out = []
        for term in self:
            out.extend( term.get_variable_names() )
        return list( set( out ) )

    ##
    # 24.07.2006, c
    # 02.08.2006
    def get_material_names( self ):
        out = []
        for term in self:
            out.extend( term.get_material_names() )
        return list( set( out ) )

    ##
    # 24.07.2006, c
    # 02.08.2006
    def get_user_names( self ):
        out = []
        for term in self:
            out.extend( term.get_user_names() )
        return list( set( out ) )

    ##
    # 11.08.2006, c
    def set_current_group( self, ig ):
        for term in self:
            term.char_fun.set_current_group( ig )

Volume = 'Volume'
Surface = 'Surface'
Edge = 'Edge'
Point = 'Point'
SurfaceExtra = 'SurfaceExtra'

##
# 21.07.2006, c
class Term( Struct ):
    name = ''
    arg_types = ()
    geometry = []

    @staticmethod
    def from_desc(constructor, desc, regions):
        try:
            region = regions[desc.region]
        except IndexError:
            raise KeyError('region "%s" does not exist!' % desc.region)
        obj = constructor(desc.name, desc.sign,
                          region=region, integral_name=desc.integral)

        arg_names = []
        arg_steps = {}
        arg_derivatives = {}
        arg_traces = {}
        for arg in desc.args:
            trace = False
            derivative = None

            if isinstance(arg[1], int):
                name, step = arg

            else:
                kind = arg[0]
                name, step = arg[1]
                if kind == 'd':
                    derivative = arg[2]
                elif kind == 'tr':
                    trace = True

            arg_names.append( name )
            arg_steps[name] = step
            arg_derivatives[name] = derivative
            arg_traces[name] = trace

        obj.arg_names = arg_names
        obj.arg_steps = arg_steps
        obj.arg_derivatives = arg_derivatives
        obj.arg_traces = arg_traces

        return obj

    def __init__(self, name, sign, region=None, integral_name=None,
                 dof_conn_type='volume', function=None):
        self.name = name
        self.sign = sign
        self.ats = list(self.arg_types)

        self.char_fun = CharacteristicFunction(region)
        self.region = region
        self.integral_name = integral_name
        self.dof_conn_type = dof_conn_type
        self.function = get_default(function,
                                    self.get_default_attr('function'), None)
        self.step = 0
        self.dt = 1.0
        self.has_integral = True
        self.has_region = True
        self.has_geometry = True
        
        self.itype = itype = None
        aux = re.compile('([a-z]+)_.*').match(name)
        if aux:
            itype = aux.group(1)<commit_msg>start refactoring of terms - support basic arithmetics<commit_after>from sfepy.base.base import *
try:
    from sfepy.terms.extmods import terms
except (ImportError, AttributeError):
    from sfepy.base.base import output
    msg = 'sfepy extension modules are not compiled!\ntype "make"'
    raise ImportError( msg )
from sfepy.base.la import split_range, combine
#from sfepy.base.ioutils import read_cache_data, write_cache_data

_match_var = re.compile( '^virtual$|^state(_[_a-zA-Z0-9]+)?$'\
                        + '|^parameter(_[_a-zA-Z0-9]+)?$' ).match
_match_state = re.compile( '^state(_[_a-zA-Z0-9]+)?$' ).match
_match_parameter = re.compile( '^parameter(_[_a-zA-Z0-9]+)?$' ).match
_match_material = re.compile( '^material(_[_a-zA-Z0-9]+)?$' ).match
_match_material_root = re.compile( '(.+)\.(.*)' ).match

def vector_chunk_generator( total_size, chunk_size, shape_in,
                            zero = False, set_shape = True, dtype = nm.float64 ):
    if not chunk_size:
        chunk_size = total_size
    shape = list( shape_in )

    sizes = split_range( total_size, chunk_size )
    ii = nm.array( 0, dtype = nm.int32 )
    for size in sizes:
        chunk = nm.arange( size, dtype = nm.int32 ) + ii
        if set_shape:
            shape[0] = size
        if zero:
            out = nm.zeros( shape, dtype = dtype )
        else:
            out = nm.empty( shape, dtype = dtype )
        yield out, chunk
        ii += size

##
# 22.01.2006, c
class CharacteristicFunction( Struct ):
    ##
    # c: 22.01.2006, r: 09.05.2008
    def __init__( self, region ):
        self.igs = region.igs
        self.region = region
        self.i_current = None
        self.local_chunk = None
        self.ig = None

    def __call__(self, chunk_size, shape_in, zero=False, set_shape=True,
                  ret_local_chunk=False, dtype=nm.float64):
        els = self.region.cells[self.ig]
        for out, chunk in vector_chunk_generator( els.shape[0], chunk_size,
                                                  shape_in, zero, set_shape,
                                                  dtype ):
            self.local_chunk = chunk

            if ret_local_chunk:
                yield out, chunk
            else:
                yield out, els[chunk]
                
        self.local_chunk = None

    ##
    # 11.08.2006, c
    # 27.02.2007
    def set_current_group( self, ig ):
        self.ig = ig
        
    ##
    # 05.09.2006, c
    def get_local_chunk( self ):
        return self.local_chunk

class Terms(Container):

    def __init__(self, objs=None):
        Container.__init__(self, objs=objs)

        self.update_expression()

    def insert(self, ii, obj):
        Container.insert(self, ii, obj)
        self.update_expression()

    def append(self, obj):
        Container.append(self, obj)
        self.update_expression()

    def update_expression(self):
        self.expression = []
        for term in self:
            aux = [term.sign, term.name, term.integral, term.region.name]
            aux += [arg.name for arg in term._args]
            self.expression.append(aux)

    def __mul__(self, other):
        out = Terms()
        for name, term in self.iteritems():
            out.append(term * other)

        return out

    def __rmul__(self, other):
        return self * other

    def __add__(self, other):
        if isinstance(other, Term):
            out = self.copy()
            out.append(other)

        elif isinstance(other, Terms):
            out = Terms(self._objs + other._objs)

        else:
            raise ValueError('cannot add Terms with %s!' % other)

        return out
        
    def __radd__(self, other):
        return self + other

    def __sub__(self, other):
        if isinstance(other, Term):
            out = self + (-other)

        elif isinstance(other, Terms):
            out = self + (-other)

        else:
            raise ValueError('cannot subtract Terms with %s!' % other)

        return out

    def __rsub__(self, other):
        return -self + other

    def __pos__(self):
        return self

    def __neg__(self):
        return -1.0 * self

    ##
    # 24.07.2006, c
    def classify_args( self, variables ):
        for term in self:
            term.classify_args( variables )
            
    ##
    # 24.07.2006, c
    # 02.08.2006
    def get_variable_names( self ):
        out = []
        for term in self:
            out.extend( term.get_variable_names() )
        return list( set( out ) )

    ##
    # 24.07.2006, c
    # 02.08.2006
    def get_material_names( self ):
        out = []
        for term in self:
            out.extend( term.get_material_names() )
        return list( set( out ) )

    ##
    # 24.07.2006, c
    # 02.08.2006
    def get_user_names( self ):
        out = []
        for term in self:
            out.extend( term.get_user_names() )
        return list( set( out ) )

    ##
    # 11.08.2006, c
    def set_current_group( self, ig ):
        for term in self:
            term.char_fun.set_current_group( ig )

Volume = 'Volume'
Surface = 'Surface'
Edge = 'Edge'
Point = 'Point'
SurfaceExtra = 'SurfaceExtra'

class Term(Struct):
    name = ''
    arg_types = ()
    geometry = []

    def __init__(self, name, integral, region, *args, **kwargs):

        self.name = name
        self.integral = integral
        self.region = region
        self._args = args
        self._kwargs = kwargs

        self.sign = 1.0

    def __mul__(self, other):
        success = False
        try:
            mul = float(other)
        except:
            pass
        else:
            success = True

        if not success:
            try:
                mul = complex(other)
            except:
                pass
            else:
                success = True
                
        if not success:
            raise ValueError('cannot multiply Term with %s!' % other)

        out = self.copy(name=self.name)

        out.sign = mul * self.sign

        return out

    def __rmul__(self, other):
        return self * other

    def __add__(self, other):
        if isinstance(other, Term):
            out = Terms([self, other])

        else:
            out = NotImplemented

        return out

    def __sub__(self, other):
        if isinstance(other, Term):
            out = Terms([self, -1.0 * other])

        else:
            out = NotImplemented

        return out

    def __pos__(self):
        return self

    def __neg__(self):
        out = -1.0 * self
        return out

    @staticmethod
    def from_desc(constructor, desc, regions):
        try:
            region = regions[desc.region]
        except IndexError:
            raise KeyError('region "%s" does not exist!' % desc.region)
        obj = constructor(desc.name, desc.sign,
                          region=region, integral_name=desc.integral)

        arg_names = []
        arg_steps = {}
        arg_derivatives = {}
        arg_traces = {}
        for arg in desc.args:
            trace = False
            derivative = None

            if isinstance(arg[1], int):
                name, step = arg

            else:
                kind = arg[0]
                name, step = arg[1]
                if kind == 'd':
                    derivative = arg[2]
                elif kind == 'tr':
                    trace = True

            arg_names.append( name )
            arg_steps[name] = step
            arg_derivatives[name] = derivative
            arg_traces[name] = trace

        obj.arg_names = arg_names
        obj.arg_steps = arg_steps
        obj.arg_derivatives = arg_derivatives
        obj.arg_traces = arg_traces

        return obj

    def _init(self, name, sign, region=None, integral_name=None,
              dof_conn_type='volume', function=None):
        self.name = name
        self.sign = sign
        self.ats = list(self.arg_types)

        self.char_fun = CharacteristicFunction(region)
        self.region = region
        self.integral_name = integral_name
        self.dof_conn_type = dof_conn_type
        self.function = get_default(function,
                                    self.get_default_attr('function'), None)
        self.step = 0
        self.dt = 1.0
        self.has_integral = True
        self.has_region = True
        self.has_geometry = True
        
        self.itype = itype = None
        aux = re.compile('([a-z]+)_.*').match(name)
        if aux:
            itype = aux.group(1)
{'fraction_non_alphanumeric': 0.10827889804032945, 'fraction_numerical': 0.02172678216415791, 'mean_word_length': 1.6676136363636365, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1960909', 'n_tokens_mistral': 4522, 'n_tokens_neox': 4186, 'n_words': 1047}