def altenative_dot(self, o, a, b): # TODO: Test this ash = a.ufl_shape bsh = b.ufl_shape ai = indices(len(ash) - 1) bi = indices(len(bsh) - 1) # Simplification for tensors where the dot-sum dimension has # length 1 if ash[-1] == 1: k = (FixedIndex(0),) else: k = (Index(),) # Potentially creates a single IndexSum over a Product s = a[ai+k]*b[k+bi] return as_tensor(s, ai+bi)
def alternative_inner(self, o, a, b): # TODO: Test this ash = a.ufl_shape bsh = b.ufl_shape if ash != bsh: error("Nonmatching shapes.") # Simplification for tensors with one or more dimensions of # length 1 ii = [] zi = FixedIndex(0) for n in ash: if n == 1: ii.append(zi) else: ii.append(Index()) ii = tuple(ii) # ii = indices(len(a.ufl_shape)) # Potentially creates multiple IndexSums over a Product s = a[ii]*Conj(b[ii]) return s
def create_slice_indices(component, shape, fi): all_indices = [] slice_indices = [] repeated_indices = [] free_indices = [] for ind in component: if isinstance(ind, Index): all_indices.append(ind) if ind.count() in fi or ind in free_indices: repeated_indices.append(ind) free_indices.append(ind) elif isinstance(ind, FixedIndex): if int(ind) >= shape[len(all_indices)]: error("Index out of bounds.") all_indices.append(ind) elif isinstance(ind, int): if int(ind) >= shape[len(all_indices)]: error("Index out of bounds.") all_indices.append(FixedIndex(ind)) elif isinstance(ind, slice): if ind != slice(None): error("Only full slices (:) allowed.") i = Index() slice_indices.append(i) all_indices.append(i) elif ind == Ellipsis: er = len(shape) - len(component) + 1 ii = indices(er) slice_indices.extend(ii) all_indices.extend(ii) else: error("Not expecting {0}.".format(ind)) if len(all_indices) != len(shape): error("Component and shape length don't match.") return tuple(all_indices), tuple(slice_indices), tuple(repeated_indices)
def analyse_key(ii, rank): """Takes something the user might input as an index tuple inside [], which could include complete slices (:) and ellipsis (...), and returns tuples of actual UFL index objects. The return value is a tuple (indices, axis_indices), each being a tuple of IndexBase instances. The return value 'indices' corresponds to all input objects of these types: - Index - FixedIndex - int => Wrapped in FixedIndex The return value 'axis_indices' corresponds to all input objects of these types: - Complete slice (:) => Replaced by a single new index - Ellipsis (...) => Replaced by multiple new indices """ # Wrap in tuple if not isinstance(ii, (tuple, MultiIndex)): ii = (ii, ) else: # Flatten nested tuples, happens with f[...,ii] where ii is a # tuple of indices jj = [] for j in ii: if isinstance(j, (tuple, MultiIndex)): jj.extend(j) else: jj.append(j) ii = tuple(jj) # Convert all indices to Index or FixedIndex objects. If there is # an ellipsis, split the indices into before and after. axis_indices = set() pre = [] post = [] indexlist = pre for i in ii: if i == Ellipsis: # Switch from pre to post list when an ellipsis is # encountered if indexlist is not pre: error("Found duplicate ellipsis.") indexlist = post else: # Convert index to a proper type if isinstance(i, numbers.Integral): idx = FixedIndex(i) elif isinstance(i, IndexBase): idx = i elif isinstance(i, slice): if i == slice(None): idx = Index() axis_indices.add(idx) else: # TODO: Use ListTensor to support partial slices? error( "Partial slices not implemented, only complete slices like [:]" ) else: error("Can't convert this object to index: %s" % (i, )) # Store index in pre or post list indexlist.append(idx) # Handle ellipsis as a number of complete slices, that is create a # number of new axis indices num_axis = rank - len(pre) - len(post) if indexlist is post: ellipsis_indices = indices(num_axis) axis_indices.update(ellipsis_indices) else: ellipsis_indices = () # Construct final tuples to return all_indices = tuple(chain(pre, ellipsis_indices, post)) axis_indices = tuple(i for i in all_indices if i in axis_indices) return all_indices, axis_indices
def compileUFL(form, patch, *args, **kwargs): if isinstance(form, Equation): form = form.lhs - form.rhs if not isinstance(form, Form): raise Exception("ufl.Form expected.") if len(form.arguments()) < 2: raise Exception("ConservationLaw model requires form with at least two arguments.") phi_, u_ = form.arguments() if phi_.ufl_function_space().scalar: phi = TestFunction(phi_.ufl_function_space().toVectorSpace()) form = replace(form,{phi_:phi[0]}) else: phi = phi_ if u_.ufl_function_space().scalar: u = TrialFunction(u_.ufl_function_space().toVectorSpace()) form = replace(form,{u_:u[0]}) else: u = u_ _, coeff_ = extract_arguments_and_coefficients(form) coeff_ = set(coeff_) # added for dirichlet treatment same as conservationlaw model dirichletBCs = [arg for arg in args if isinstance(arg, DirichletBC)] # remove the dirichletBCs arg = [arg for arg in args if not isinstance(arg, DirichletBC)] for dBC in dirichletBCs: _, coeff__ = extract_arguments_and_coefficients(dBC.ufl_value) coeff_ |= set(coeff__) if patch is not None: for a in patch: try: _, coeff__ = extract_arguments_and_coefficients(a) coeff_ |= set(coeff__) except: pass # a might be a float/int and not a ufl expression coeff = {c : c.toVectorCoefficient()[0] for c in coeff_ if len(c.ufl_shape) == 0 and not c.is_cellwise_constant()} form = replace(form,coeff) for bc in dirichletBCs: bc.ufl_value = replace(bc.ufl_value, coeff) if patch is not None: patch = [a if not isinstance(a, Expr) else replace(a,coeff) for a in patch] phi = form.arguments()[0] dimRange = phi.ufl_shape[0] u = form.arguments()[1] du = Grad(u) d2u = Grad(du) ubar = Coefficient(u.ufl_function_space()) dubar = Grad(ubar) d2ubar = Grad(dubar) dimDomain = u.ufl_shape[0] x = SpatialCoordinate(form.ufl_cell()) try: field = u.ufl_function_space().field except AttributeError: field = "double" # if exact solution is passed in subtract a(u,.) from the form if "exact" in kwargs: b = replace(form, {u: as_vector(kwargs["exact"])} ) form = form - b dform = apply_derivatives(derivative(action(form, ubar), ubar, u)) source, flux, boundarySource = splitUFLForm(form) linSource, linFlux, linBoundarySource = splitUFLForm(dform) fluxDivergence, _, _ = splitUFLForm(inner(source.as_ufl() - div(flux.as_ufl()), phi) * dx(0)) # split linNVSource off linSource # linSources = splitUFL2(u, du, d2u, linSource) # linNVSource = linSources[2] # linSource = linSources[0] + linSources[1] if patch is not None: model = ConservationLawModel(dimDomain, dimRange, u, modelSignature(form,*patch,*args)) else: model = ConservationLawModel(dimDomain, dimRange, u, modelSignature(form,None,*args)) model._replaceCoeff = coeff model.hasNeumanBoundary = not boundarySource.is_zero() #expandform = expand_indices(expand_derivatives(expand_compounds(equation.lhs))) #if expandform == adjoint(expandform): # model.symmetric = 'true' model.field = field dirichletBCs = [arg for arg in args if isinstance(arg, DirichletBC)] # deprecated # if "dirichlet" in kwargs: # dirichletBCs += [DirichletBC(u.ufl_function_space(), as_vector(value), bndId) for bndId, value in kwargs["dirichlet"].items()] uflCoefficients = set(form.coefficients()) for bc in dirichletBCs: _, c = extract_arguments_and_coefficients(bc.ufl_value) uflCoefficients |= set(c) if patch is not None: for a in patch: if isinstance(a, Expr): _, c = extract_arguments_and_coefficients(a) uflCoefficients |= set(c) constants = dict() coefficients = dict() for coefficient in uflCoefficients: try: name = getattr(coefficient, "name") except AttributeError: name = str(coefficient) if coefficient.is_cellwise_constant(): try: parameter = getattr(coefficient, "parameter") except AttributeError: parameter = None if len(coefficient.ufl_shape) == 0: constants[coefficient] = model.addConstant('double', name=name, parameter=parameter) elif len(coefficient.ufl_shape) == 1: constants[coefficient] = model.addConstant('Dune::FieldVector< double, ' + str(coefficient.ufl_shape[0]) + ' >', name=name, parameter=parameter) else: Exception('Currently, only scalars and vectors are supported as constants') else: shape = coefficient.ufl_shape[0] try: coefficients[coefficient] = model.addCoefficient( shape, coefficient.cppTypeName, name=name, field=coefficient.ufl_function_space().field) except AttributeError: coefficients[coefficient] = model.addCoefficient( shape, coefficient.cppTypeName, name=name) model.coefficients = coefficients model.constants = constants tempVars = kwargs.get("tempVars", True) predefined = {u: model.arg_u, du: model.arg_du, d2u: model.arg_d2u} predefined[x] = UnformattedExpression('auto', 'entity().geometry().global( Dune::Fem::coordinate( ' + model.arg_x.name + ' ) )') model.predefineCoefficients(predefined,'x') model.source = generateCode(predefined, source, tempVars=tempVars) model.flux = generateCode(predefined, flux, tempVars=tempVars) predefined.update({ubar: model.arg_ubar, dubar: model.arg_dubar, d2ubar: model.arg_d2ubar}) model.linSource = generateCode(predefined, linSource, tempVars=tempVars) model.linFlux = generateCode(predefined, linFlux, tempVars=tempVars) # model.linNVSource = generateCode({u: arg, du: darg, d2u: d2arg, ubar: argbar, dubar: dargbar, d2ubar: d2argbar}, linNVSource, model.coefficients, tempVars) predefined = {u: model.arg_u} predefined[x] = UnformattedExpression('auto', 'entity().geometry().global( Dune::Fem::coordinate( ' + model.arg_x.name + ' ) )') model.predefineCoefficients(predefined,'x') model.alpha = generateCode(predefined, boundarySource, tempVars=tempVars) predefined.update({ubar: model.arg_ubar}) model.linAlpha = generateCode(predefined, linBoundarySource, tempVars=tempVars) predefined = {u: model.arg_u, du: model.arg_du, d2u: model.arg_d2u} predefined[x] = UnformattedExpression('auto', 'entity().geometry().global( Dune::Fem::coordinate( ' + model.arg_x.name + ' ) )') model.predefineCoefficients(predefined,'x') model.fluxDivergence = generateCode(predefined, fluxDivergence, tempVars=tempVars) if dirichletBCs: model.hasDirichletBoundary = True predefined = {} predefined[x] = UnformattedExpression('auto', 'entity().geometry().global( Dune::Fem::coordinate( ' + model.arg_x.name + ' ) )') model.predefineCoefficients(predefined,'x') maxId = 0 codeDomains = [] bySubDomain = dict() neuman = [] for bc in dirichletBCs: if bc.subDomain in bySubDomain: raise Exception('Multiply defined Dirichlet boundary for subdomain ' + str(bc.subDomain)) if not isinstance(bc.functionSpace, (FunctionSpace, FiniteElementBase)): raise Exception('Function space must either be a ufl.FunctionSpace or a ufl.FiniteElement') if isinstance(bc.functionSpace, FunctionSpace) and (bc.functionSpace != u.ufl_function_space()): raise Exception('Space of trial function and dirichlet boundary function must be the same - note that boundary conditions on subspaces are not available, yet') if isinstance(bc.functionSpace, FiniteElementBase) and (bc.functionSpace != u.ufl_element()): raise Exception('Cannot handle boundary conditions on subspaces, yet') if isinstance(bc.value, list): neuman = [i for i, x in enumerate(bc.value) if x == None] else: neuman = [] value = ExprTensor(u.ufl_shape) for key in value.keys(): value[key] = Indexed(bc.ufl_value, MultiIndex(tuple(FixedIndex(k) for k in key))) if isinstance(bc.subDomain,int): bySubDomain[bc.subDomain] = value,neuman maxId = max(maxId, bc.subDomain) else: domain = ExprTensor(()) for key in domain.keys(): domain[key] = Indexed(bc.subDomain, MultiIndex(tuple(FixedIndex(k) for k in key))) codeDomains.append( (value,neuman,domain) ) defaultCode = [] defaultCode.append(Declaration(Variable('int', 'domainId'))) defaultCode.append(Declaration(Variable('auto', 'tmp0'), initializer=UnformattedExpression('auto','intersection.geometry().center()'))) for i,v in enumerate(codeDomains): block = Block() defaultCode.append( generateDirichletDomainCode(predefined, v[2], tempVars=tempVars)) defaultCode.append('if (domainId)') block = UnformattedBlock() block.append('std::fill( dirichletComponent.begin(), dirichletComponent.end(), ' + str(maxId+i+1) + ' );') if len(v[1])>0: [block.append('dirichletComponent[' + str(c) + '] = 0;') for c in v[1]] block.append('return true;') defaultCode.append(block) defaultCode.append(return_(False)) bndId = Variable('const int', 'bndId') getBndId = UnformattedExpression('int', 'BoundaryIdProviderType::boundaryId( ' + model.arg_i.name + ' )') switch = SwitchStatement(bndId, default=defaultCode) for i,v in bySubDomain.items(): code = [] if len(v[1])>0: [code.append('dirichletComponent[' + str(c) + '] = 0;') for c in v[1]] code.append(return_(True)) switch.append(i, code) model.isDirichletIntersection = [Declaration(bndId, initializer=getBndId), UnformattedBlock('std::fill( dirichletComponent.begin(), dirichletComponent.end(), ' + bndId.name + ' );'), switch ] switch = SwitchStatement(model.arg_bndId, default=assign(model.arg_r, construct("RRangeType", 0))) for i, v in bySubDomain.items(): switch.append(i, generateDirichletCode(predefined, v[0], tempVars=tempVars)) for i,v in enumerate(codeDomains): switch.append(i+maxId+1, generateDirichletCode(predefined, v[0], tempVars=tempVars)) model.dirichlet = [switch] return model
def multi_index(self, x): comp = self._multi_index_values(x) return MultiIndex(tuple(FixedIndex(i) for i in comp))
def _compileUFL(integrands, form, *args, tempVars=True): if isinstance(form, Equation): form = form.lhs - form.rhs if not isinstance(form, Form): raise ValueError("ufl.Form or ufl.Equation expected.") # added for dirichlet treatment same as conservationlaw model dirichletBCs = [arg for arg in args if isinstance(arg, DirichletBC)] uflExpr = [form] + [bc.ufl_value for bc in dirichletBCs] if len(form.arguments()) < 2: raise ValueError( "Integrands model requires form with at least two arguments.") x = SpatialCoordinate(form.ufl_cell()) n = FacetNormal(form.ufl_cell()) cellVolume = CellVolume(form.ufl_cell()) maxCellEdgeLength = MaxCellEdgeLength(form.ufl_cell()) minCellEdgeLength = MinCellEdgeLength(form.ufl_cell()) facetArea = FacetArea(form.ufl_cell()) maxFacetEdgeLength = MaxFacetEdgeLength(form.ufl_cell()) minFacetEdgeLength = MinFacetEdgeLength(form.ufl_cell()) phi, u = form.arguments() ubar = Coefficient(u.ufl_function_space()) derivatives = gatherDerivatives(form, [phi, u]) derivatives_phi = derivatives[0] derivatives_u = derivatives[1] derivatives_ubar = map_expr_dags(Replacer({u: ubar}), derivatives_u) try: integrands.field = u.ufl_function_space().field except AttributeError: pass integrals = splitForm(form, [phi]) dform = apply_derivatives(derivative(action(form, ubar), ubar, u)) linearizedIntegrals = splitForm(dform, [phi, u]) if not set( integrals.keys()) <= {'cell', 'exterior_facet', 'interior_facet'}: raise Exception('unknown integral encountered in ' + str(set(integrals.keys())) + '.') if 'cell' in integrals.keys(): arg = Variable(integrands.domainValueTuple, 'u') predefined = { derivatives_u[i]: arg[i] for i in range(len(derivatives_u)) } predefined[x] = integrands.spatialCoordinate('x') predefined[cellVolume] = integrands.cellVolume() predefined[maxCellEdgeLength] = maxEdgeLength( integrands.cellGeometry()) predefined[minCellEdgeLength] = minEdgeLength( integrands.cellGeometry()) integrands.predefineCoefficients(predefined, False) integrands.interior = generateUnaryCode(predefined, derivatives_phi, integrals['cell'], tempVars=tempVars) predefined = { derivatives_ubar[i]: arg[i] for i in range(len(derivatives_u)) } predefined[x] = integrands.spatialCoordinate('x') predefined[cellVolume] = integrands.cellVolume() predefined[maxCellEdgeLength] = maxEdgeLength( integrands.cellGeometry()) predefined[minCellEdgeLength] = minEdgeLength( integrands.cellGeometry()) integrands.predefineCoefficients(predefined, False) integrands.linearizedInterior = generateUnaryLinearizedCode( predefined, derivatives_phi, derivatives_u, linearizedIntegrals.get('cell'), tempVars=tempVars) if 'exterior_facet' in integrals.keys(): arg = Variable(integrands.domainValueTuple, 'u') predefined = { derivatives_u[i]: arg[i] for i in range(len(derivatives_u)) } predefined[x] = integrands.spatialCoordinate('x') predefined[n] = integrands.facetNormal('x') predefined[cellVolume] = integrands.cellVolume() predefined[maxCellEdgeLength] = maxEdgeLength( integrands.cellGeometry()) predefined[minCellEdgeLength] = minEdgeLength( integrands.cellGeometry()) predefined[facetArea] = integrands.facetArea() predefined[maxFacetEdgeLength] = maxEdgeLength( integrands.facetGeometry()) predefined[minFacetEdgeLength] = minEdgeLength( integrands.facetGeometry()) integrands.predefineCoefficients(predefined, False) integrands.boundary = generateUnaryCode(predefined, derivatives_phi, integrals['exterior_facet'], tempVars=tempVars) predefined = { derivatives_ubar[i]: arg[i] for i in range(len(derivatives_u)) } predefined[x] = integrands.spatialCoordinate('x') predefined[n] = integrands.facetNormal('x') predefined[cellVolume] = integrands.cellVolume() predefined[maxCellEdgeLength] = maxEdgeLength( integrands.cellGeometry()) predefined[minCellEdgeLength] = minEdgeLength( integrands.cellGeometry()) predefined[facetArea] = integrands.facetArea() predefined[maxFacetEdgeLength] = maxEdgeLength( integrands.facetGeometry()) predefined[minFacetEdgeLength] = minEdgeLength( integrands.facetGeometry()) integrands.predefineCoefficients(predefined, False) integrands.linearizedBoundary = generateUnaryLinearizedCode( predefined, derivatives_phi, derivatives_u, linearizedIntegrals.get('exterior_facet'), tempVars=tempVars) if 'interior_facet' in integrals.keys(): argIn = Variable(integrands.domainValueTuple, 'uIn') argOut = Variable(integrands.domainValueTuple, 'uOut') predefined = { derivatives_u[i](s): arg[i] for i in range(len(derivatives_u)) for s, arg in (('+', argIn), ('-', argOut)) } predefined[x] = integrands.spatialCoordinate('xIn') predefined[n('+')] = integrands.facetNormal('xIn') predefined[cellVolume('+')] = integrands.cellVolume('Side::in') predefined[cellVolume('-')] = integrands.cellVolume('Side::out') predefined[maxCellEdgeLength('+')] = maxEdgeLength( integrands.cellGeometry('Side::in')) predefined[maxCellEdgeLength('-')] = maxEdgeLength( integrands.cellGeometry('Side::out')) predefined[minCellEdgeLength('+')] = minEdgeLength( integrands.cellGeometry('Side::in')) predefined[minCellEdgeLength('-')] = minEdgeLength( integrands.cellGeometry('Side::out')) predefined[facetArea] = integrands.facetArea() predefined[maxFacetEdgeLength] = maxEdgeLength( integrands.facetGeometry()) predefined[minFacetEdgeLength] = minEdgeLength( integrands.facetGeometry()) integrands.predefineCoefficients(predefined, True) integrands.skeleton = generateBinaryCode(predefined, derivatives_phi, integrals['interior_facet'], tempVars=tempVars) predefined = { derivatives_ubar[i](s): arg[i] for i in range(len(derivatives_u)) for s, arg in (('+', argIn), ('-', argOut)) } predefined[x] = integrands.spatialCoordinate('xIn') predefined[n('+')] = integrands.facetNormal('xIn') predefined[cellVolume('+')] = integrands.cellVolume('Side::in') predefined[cellVolume('-')] = integrands.cellVolume('Side::out') predefined[maxCellEdgeLength('+')] = maxEdgeLength( integrands.cellGeometry('Side::in')) predefined[maxCellEdgeLength('-')] = maxEdgeLength( integrands.cellGeometry('Side::out')) predefined[minCellEdgeLength('+')] = minEdgeLength( integrands.cellGeometry('Side::in')) predefined[minCellEdgeLength('-')] = minEdgeLength( integrands.cellGeometry('Side::out')) predefined[facetArea] = integrands.facetArea() predefined[maxFacetEdgeLength] = maxEdgeLength( integrands.facetGeometry()) predefined[minFacetEdgeLength] = minEdgeLength( integrands.facetGeometry()) integrands.predefineCoefficients(predefined, True) integrands.linearizedSkeleton = generateBinaryLinearizedCode( predefined, derivatives_phi, derivatives_u, linearizedIntegrals.get('interior_facet'), tempVars=tempVars) if dirichletBCs: integrands.hasDirichletBoundary = True predefined = {} # predefined[x] = UnformattedExpression('auto', 'entity().geometry().global( Dune::Fem::coordinate( ' + integrands.arg_x.name + ' ) )') predefined[x] = UnformattedExpression( 'auto', 'intersection.geometry().center( )') integrands.predefineCoefficients(predefined, False) maxId = 0 codeDomains = [] bySubDomain = dict() neuman = [] wholeDomain = None for bc in dirichletBCs: if bc.subDomain in bySubDomain: raise Exception( 'Multiply defined Dirichlet boundary for subdomain ' + str(bc.subDomain)) if not isinstance(bc.functionSpace, (FunctionSpace, FiniteElementBase)): raise Exception( 'Function space must either be a ufl.FunctionSpace or a ufl.FiniteElement' ) if isinstance(bc.functionSpace, FunctionSpace) and ( bc.functionSpace != u.ufl_function_space()): raise Exception( 'Space of trial function and dirichlet boundary function must be the same - note that boundary conditions on subspaces are not available, yet' ) if isinstance(bc.functionSpace, FiniteElementBase) and ( bc.functionSpace != u.ufl_element()): raise Exception( 'Cannot handle boundary conditions on subspaces, yet') if isinstance(bc.value, list): neuman = [i for i, x in enumerate(bc.value) if x == None] else: neuman = [] value = ExprTensor(u.ufl_shape) for key in value.keys(): value[key] = Indexed( bc.ufl_value, MultiIndex(tuple(FixedIndex(k) for k in key))) if bc.subDomain is None: wholeDomain = value, neuman elif isinstance(bc.subDomain, int): bySubDomain[bc.subDomain] = value, neuman maxId = max(maxId, bc.subDomain) else: domain = ExprTensor(()) for key in domain.keys(): domain[key] = Indexed( bc.subDomain, MultiIndex(tuple(FixedIndex(k) for k in key))) codeDomains.append((value, neuman, domain)) defaultCode = [] if len(codeDomains) > 0: defaultCode.append(Declaration(Variable('int', 'domainId'))) # defaultCode.append(Declaration(Variable('auto', 'x'), # initializer=UnformattedExpression('auto','intersection.geometry().center()'))) for i, v in enumerate(codeDomains): block = Block() block.append( generateDirichletDomainCode(predefined, v[2], tempVars=tempVars)) block.append('if (domainId)') ifBlock = UnformattedBlock() ifBlock.append( 'std::fill( dirichletComponent.begin(), dirichletComponent.end(), ' + str(maxId + i + 2) + ' );') if len(v[1]) > 0: [ ifBlock.append('dirichletComponent[' + str(c) + '] = 0;') for c in v[1] ] ifBlock.append('return true;') block.append(ifBlock) defaultCode.append(block) if wholeDomain is not None: block = UnformattedBlock() block.append( 'std::fill( dirichletComponent.begin(), dirichletComponent.end(), ' + str(maxId + 1) + ' );') if len(wholeDomain[1]) > 0: [ block.append('dirichletComponent[' + str(c) + '] = 0;') for c in wholeDomain[1] ] block.append('return true;') defaultCode.append(block) defaultCode.append(return_(False)) bndId = Variable('const int', 'bndId') getBndId = UnformattedExpression( 'int', 'BoundaryIdProviderType::boundaryId( ' + integrands.arg_i.name + ' )') # getBndId = UnformattedExpression('int', 'boundaryIdGetter_.boundaryId( ' + integrands.arg_i.name + ' )') switch = SwitchStatement(bndId, default=defaultCode) for i, v in bySubDomain.items(): code = [] if len(v[1]) > 0: [ code.append('dirichletComponent[' + str(c) + '] = 0;') for c in v[1] ] code.append(return_(True)) switch.append(i, code) integrands.isDirichletIntersection = [ Declaration(bndId, initializer=getBndId), UnformattedBlock( 'std::fill( dirichletComponent.begin(), dirichletComponent.end(), ' + bndId.name + ' );'), switch ] predefined[x] = UnformattedExpression( 'auto', 'entity().geometry().global( Dune::Fem::coordinate( ' + integrands.arg_x.name + ' ) )') if wholeDomain is None: defaultCode = assign(integrands.arg_r, construct("RRangeType", 0)) else: defaultCode = generateDirichletCode(predefined, wholeDomain[0], tempVars=tempVars) switch = SwitchStatement(integrands.arg_bndId, default=defaultCode) for i, v in bySubDomain.items(): switch.append( i, generateDirichletCode(predefined, v[0], tempVars=tempVars)) for i, v in enumerate(codeDomains): switch.append( i + maxId + 2, generateDirichletCode(predefined, v[0], tempVars=tempVars)) integrands.dirichlet = [switch] return integrands