def assemble_matrix(mtx, equation, variables, materials, chunk_size=1000, group_can_fail=True, **kwargs): """Assemble tangent matrix. Supports backward time difference of state variables.""" if not sp.isspmatrix_csr(mtx): raise TypeError, "must be CSR matrix!" tmd = (mtx.data, mtx.indptr, mtx.indices) get_a_dof_conn = variables.get_a_dof_conn for term in equation.terms: # print '>>>>>>', term.name, term.sign var_names = term.get_variable_names() args = build_args(term, variables, materials, **kwargs) vn = term.get_virtual_name(variables=variables) sns = term.get_state_names(variables=variables) dc_type = term.get_dof_conn_type() for ig in term.iter_groups(): rdc = get_a_dof_conn(vn, True, dc_type, ig) # print vn, rdc.shape for sn in sns: cdc = get_a_dof_conn(sn, False, dc_type, ig) # print sn, cdc.shape # pause() for mtx_in_els, iels, status in term(diff_var=sn, chunk_size=chunk_size, **args): if status != 0: raise StopIteration(status, term, equation, var_name_col) assert_(mtx_in_els.shape[2:] == (rdc.shape[1], cdc.shape[1])) sign = term.sign if term.arg_derivatives[sn]: sign *= 1.0 / term.dt if mtx.dtype == nm.float64: fem.assemble_matrix(tmd[0], tmd[1], tmd[2], mtx_in_els, iels, sign, rdc, cdc) else: assert_(mtx.dtype == nm.complex128) sign = nm.array(term.sign, dtype=nm.complex128) fem.assemble_matrix_complex( tmd[0].real, tmd[0].imag, tmd[1], tmd[2], mtx_in_els.real, mtx_in_els.imag, iels, float(sign.real), float(sign.imag), rdc, cdc, )
def assemble_vector(vec, equation, variables, materials, chunk_size=1000, **kwargs): get_a_dof_conn = variables.get_a_dof_conn for term in equation.terms: ## print '>>>>>>', term.name, term.sign var_names = term.get_variable_names() args = build_args(term, variables, materials, **kwargs) vn = term.get_virtual_name(variables=variables) dc_type = term.get_dof_conn_type() ## print args ## print vn ## print dc_type for ig in term.iter_groups(): dc = get_a_dof_conn(vn, True, dc_type, ig) ## print vn, dc.shape # pause() for vec_in_els, iels, status in term(chunk_size=chunk_size, **args): if status != 0: raise StopIteration(status, term, equation) check_finitness = False if check_finitness and (not nm.isfinite(vec_in_els).all()): print term.name, term.sign, ig debug() assert_(vec_in_els.shape[2] == dc.shape[1]) if vec.dtype == nm.float64: fem.assemble_vector(vec, vec_in_els, iels, term.sign, dc) else: assert_(vec.dtype == nm.complex128) sign = nm.array(term.sign, dtype=nm.complex128) fem.assemble_vector_complex( vec.real, vec.imag, vec_in_els.real, vec_in_els.imag, iels, float(sign.real), float(sign.imag), dc, )
def eval_term( state, term_desc, conf, domain, variables, materials, ts, funmod=None, chunk_size=1000, term_prefixes=None, caches=None, ret_caches=False, override=True, new_geometries=True, dw_mode="vector", tangent_matrix=None, **kwargs ): """Evaluate a term. May not succeed!""" if term_prefixes is None: term_prefixes = {} if caches is None: caches = DataCaches() equation = Equation.from_desc("tmp", term_desc, term_prefixes) equation.setup_terms(domain.regions, variables, materials, caches, kwargs) for cache in caches.itervalues(): cache.set_mode(override=override) if new_geometries: i_names = equation.get_term_integral_names() integrals = Integrals.from_conf(conf.integrals, i_names) integrals.set_quadratures(quadratures) geometries = {} equation.describe_geometry(geometries, variables, integrals) variables.data_from_state(state) if "call_mode" in kwargs: itype = kwargs["call_mode"].split("_")[0] else: # itype according to the first term in term_desc! itype = equation.terms[0].itype if itype == "dw": variables.setup_dof_conns() if not variables.has_eq_map: variables.equation_mapping(conf.ebcs, conf.epbcs, domain.regions, ts, funmod) variables.setup_lcbc_operators(conf.lcbcs, domain.regions) variables.setup_a_dof_conns() if dw_mode == "vector": residual = variables.create_stripped_state_vector() assemble_vector(residual, equation, variables, materials, chunk_size, group_can_fail=False, **kwargs) if variables.has_lcbc: op_lcbc = variables.op_lcbc residual = op_lcbc.T * residual ret_val = residual elif dw_mode == "matrix": if tangent_matrix is None: tangent_matrix = variables.create_matrix_graph() tangent_matrix.data[:] = 0.0 assemble_matrix(tangent_matrix, equation, variables, materials, chunk_size, group_can_fail=False, **kwargs) if variables.has_lcbc: op_lcbc = variables.op_lcbc tangent_matrix = op_lcbc.T * tangent_matrix * op_lcbc tangent_matrix = tangent_matrix.tocsr() tangent_matrix.sort_indices() ret_val = tangent_matrix else: print dw_mode raise ValueError elif itype == "d": kwargs.setdefault("call_mode", "d_eval") val = 0.0 for term in equation.terms: args = build_args(term, variables, materials, **kwargs) for ig in term.iter_groups(): for aux, iels, status in term(chunk_size=chunk_size, **args): val += term.sign * aux ret_val = val elif itype == "di": val = None for term in equation.terms: args = build_args(term, variables, materials, **kwargs) for ig in term.iter_groups(): for aux, iels, status in term(chunk_size=chunk_size, **args): if val is None: val = term.sign * aux else: val += term.sign * aux ret_val = val elif (itype == "de") or (itype == "dq"): val = None for term in equation.terms: args = build_args(term, variables, materials, **kwargs) for ig in term.iter_groups(): for aux, iels, status in term(chunk_size=chunk_size, **args): if val is None: val = term.sign * aux else: val = nm.concatenate((val, term.sign * aux), axis=0) ret_val = val else: raise NotImplementedError, "unknown term integration type: %s" % itype if ret_caches: return ret_val, caches else: return ret_val