def save_ebc(self, filename, force=True, default=0.0): """ Save essential boundary conditions as state variables. """ output('saving ebc...') variables = self.get_variables(auto_create=True) ebcs = Conditions.from_conf(self.conf.ebcs, self.domain.regions) epbcs = Conditions.from_conf(self.conf.epbcs, self.domain.regions) try: variables.equation_mapping(ebcs, epbcs, self.ts, self.functions, problem=self) except: output('cannot make equation mapping!') raise state = State(variables) state.fill(default) if force: vals = dict_from_keys_init(variables.state) for ii, key in enumerate(vals.iterkeys()): vals[key] = ii + 1 state.apply_ebc(force_values=vals) else: state.apply_ebc() out = state.create_output_dict(extend=True) self.save_state(filename, out=out, fill_value=default) output('...done')
def save_ebc(self, filename, force=True, default=0.0): """ Save essential boundary conditions as state variables. """ output("saving ebc...") variables = self.get_variables(auto_create=True) ebcs = Conditions.from_conf(self.conf.ebcs, self.domain.regions) epbcs = Conditions.from_conf(self.conf.epbcs, self.domain.regions) try: variables.equation_mapping(ebcs, epbcs, self.ts, self.functions, problem=self) except: output("cannot make equation mapping!") raise state = State(variables) state.fill(default) if force: vals = dict_from_keys_init(variables.state) for ii, key in enumerate(vals.iterkeys()): vals[key] = ii + 1 state.apply_ebc(force_values=vals) else: state.apply_ebc() out = state.create_output_dict(extend=True) self.save_state(filename, out=out, fill_value=default) output("...done")
def __call__(self, problem=None, data=None): from sfepy.base.base import select_by_names from sfepy.discrete.variables import Variables from sfepy.discrete.state import State from sfepy.discrete.conditions import Conditions problem = get_default(problem, self.problem) conf_ebc = select_by_names(problem.conf.ebcs, self.ebcs) conf_epbc = select_by_names(problem.conf.epbcs, self.epbcs) ebcs = Conditions.from_conf(conf_ebc, problem.domain.regions) epbcs = Conditions.from_conf(conf_epbc, problem.domain.regions) conf_variables = select_by_names(problem.conf.variables, self.variable) problem.set_variables(conf_variables) variables = Variables.from_conf(conf_variables, problem.fields) variables.equation_mapping(ebcs, epbcs, problem.ts, problem.functions) state = State(variables) state.fill(0.0) state.apply_ebc() corr_sol = CorrSolution(name=self.name, state=state.get_parts()) self.save(corr_sol, problem, variables) return corr_sol
def save_ebc(self, filename, ebcs=None, epbcs=None, force=True, default=0.0): """ Save essential boundary conditions as state variables. Parameters ---------- filename : str The output file name. ebcs : Conditions instance, optional The essential (Dirichlet) boundary conditions. If not given, `self.conf.ebcs` are used. epbcs : Conditions instance, optional The periodic boundary conditions. If not given, `self.conf.epbcs` are used. force : bool If True, sequential nonzero values are forced to individual `ebcs` so that the conditions are visible even when zero. default : float The default constant value of state vector. """ output('saving ebc...') variables = self.get_variables(auto_create=True) if ebcs is None: ebcs = Conditions.from_conf(self.conf.ebcs, self.domain.regions) if epbcs is None: epbcs = Conditions.from_conf(self.conf.epbcs, self.domain.regions) try: variables.equation_mapping(ebcs, epbcs, self.ts, self.functions, problem=self) except: output('cannot make equation mapping!') raise state = State(variables) state.fill(default) if force: vals = dict_from_keys_init(variables.state) for ii, key in enumerate(vals.iterkeys()): vals[key] = ii + 1 state.apply_ebc(force_values=vals) else: state.apply_ebc() out = state.create_output_dict(extend=True) self.save_state(filename, out=out, fill_value=default) output('...done')
def solve(self, state0=None, nls_status=None, ls_conf=None, nls_conf=None, force_values=None, var_data=None): """Solve self.equations in current time step. Parameters ---------- var_data : dict A dictionary of {variable_name : data vector} used to initialize parameter variables. """ solvers = self.get_solvers() if solvers is None: self.init_solvers(nls_status, ls_conf, nls_conf) solvers = self.get_solvers() if state0 is None: state0 = State(self.equations.variables) else: if isinstance(state0, nm.ndarray): state0 = State(self.equations.variables, vec=state0) self.equations.set_data(var_data, ignore_unknown=True) self.update_materials() state0.apply_ebc(force_values=force_values) vec0 = state0.get_reduced() self.nls_status = get_default(nls_status, self.nls_status) vec = solvers.nls(vec0, status=self.nls_status) state = state0.copy(preserve_caches=True) state.set_reduced(vec, preserve_caches=True) return state
def __init__(self, conf, problem, **kwargs): from sfepy.discrete.state import State ScipyDirect.__init__(self, conf, **kwargs) equations = problem.equations aux_state = State(equations.variables) conf.idxs = {} for bk, bv in conf.blocks.iteritems(): aux_state.fill(0.0) for jj in bv: idx = equations.variables.di.indx[jj] aux_state.vec[idx] = nm.nan aux_state.apply_ebc() vec0 = aux_state.get_reduced() conf.idxs[bk] = nm.where(nm.isnan(vec0))[0]
def __init__(self, conf, **kwargs): from sfepy.discrete.state import State ScipyDirect.__init__(self, conf, **kwargs) equations = self.problem.equations aux_state = State(equations.variables) conf.idxs = {} for bk, bv in conf.blocks.iteritems(): aux_state.fill(0.0) for jj in bv: idx = equations.variables.di.indx[jj] aux_state.vec[idx] = nm.nan aux_state.apply_ebc() vec0 = aux_state.get_reduced() conf.idxs[bk] = nm.where(nm.isnan(vec0))[0]
def init_subproblems(self, conf, **kwargs): from sfepy.discrete.state import State from sfepy.discrete import Problem from sfepy.base.conf import ProblemConf, get_standard_keywords from scipy.spatial import cKDTree as KDTree # init subproblems problem = self.context pb_vars = problem.get_variables() # get "master" DofInfo and last index pb_adi_indx = problem.equations.variables.adi.indx self.adi_indx = pb_adi_indx.copy() last_indx = -1 for ii in six.itervalues(self.adi_indx): last_indx = nm.max([last_indx, ii.stop]) # coupling variables self.cvars_to_pb = {} for jj in conf.coupling_variables: self.cvars_to_pb[jj] = [None, None] if jj in pb_vars.names: if pb_vars[jj].dual_var_name is not None: self.cvars_to_pb[jj][0] = -1 else: self.cvars_to_pb[jj][1] = -1 # init subproblems self.subpb = [] required, other = get_standard_keywords() master_prefix = output.get_output_prefix() for ii, ifname in enumerate(conf.others): sub_prefix = master_prefix[:-1] + '-sub%d:' % (ii + 1) output.set_output_prefix(sub_prefix) kwargs['master_problem'] = problem confi = ProblemConf.from_file(ifname, required, other, define_args=kwargs) pbi = Problem.from_conf(confi, init_equations=True) sti = State(pbi.equations.variables) pbi.equations.set_data(None, ignore_unknown=True) pbi.time_update() pbi.update_materials() sti.apply_ebc() pbi_vars = pbi.get_variables() output.set_output_prefix(master_prefix) self.subpb.append([pbi, sti, None]) # append "slave" DofInfo for jj in pbi_vars.names: if not (pbi_vars[jj].is_state()): continue didx = pbi.equations.variables.adi.indx[jj] ndof = didx.stop - didx.start if jj in self.adi_indx: if ndof != \ (self.adi_indx[jj].stop - self.adi_indx[jj].start): raise ValueError('DOFs do not match!') else: self.adi_indx.update( {jj: slice(last_indx, last_indx + ndof, None)}) last_indx += ndof for jj in conf.coupling_variables: if jj in pbi_vars.names: if pbi_vars[jj].dual_var_name is not None: self.cvars_to_pb[jj][0] = ii else: self.cvars_to_pb[jj][1] = ii self.subpb.append([problem, None, None]) self.cvars_to_pb_map = {} for varname, pbs in six.iteritems(self.cvars_to_pb): # match field nodes coors = [] for ii in pbs: pbi = self.subpb[ii][0] pbi_vars = pbi.get_variables() fcoors = pbi_vars[varname].field.coors dc = nm.abs(nm.max(fcoors, axis=0)\ - nm.min(fcoors, axis=0)) ax = nm.where(dc > 1e-9)[0] coors.append(fcoors[:, ax]) if len(coors[0]) != len(coors[1]): raise ValueError('number of nodes does not match!') kdtree = KDTree(coors[0]) map_12 = kdtree.query(coors[1])[1] pbi1 = self.subpb[pbs[0]][0] pbi1_vars = pbi1.get_variables() eq_map_1 = pbi1_vars[varname].eq_map pbi2 = self.subpb[pbs[1]][0] pbi2_vars = pbi2.get_variables() eq_map_2 = pbi2_vars[varname].eq_map dpn = eq_map_2.dpn nnd = map_12.shape[0] map_12_nd = nm.zeros((nnd * dpn, ), dtype=nm.int32) if dpn > 1: for ii in range(dpn): map_12_nd[ii::dpn] = map_12 * dpn + ii else: map_12_nd = map_12 idx = nm.where(eq_map_2.eq >= 0)[0] self.cvars_to_pb_map[varname] = eq_map_1.eq[map_12[idx]]
def __call__(self, rhs, x0=None, conf=None, eps_a=None, eps_r=None, i_max=None, mtx=None, status=None, **kwargs): from sfepy.discrete.state import State equations = self.context.equations aux_state = State(equations.variables) mtxi = {} for bk, bv in six.iteritems(conf.blocks): aux_state.fill(0.0) for jj in bv: idx = equations.variables.di.indx[jj] aux_state.vec[idx] = nm.nan aux_state.apply_ebc() vec0 = aux_state.get_reduced() mtxi[bk] = nm.where(nm.isnan(vec0))[0] mtxslc_s = {} mtxslc_f = {} nn = {} for ik, iv in six.iteritems(mtxi): ptr = 0 nn[ik] = len(iv) mtxslc_s[ik] = [] mtxslc_f[ik] = [] while ptr < nn[ik]: idx0 = iv[ptr:] idxrange = nm.arange(idx0[0], idx0[0] + len(idx0)) aux = nm.where(idx0 == idxrange)[0] mtxslc_s[ik].append(slice(ptr + aux[0], ptr + aux[-1] + 1)) mtxslc_f[ik].append(slice(idx0[aux][0], idx0[aux][-1] + 1)) ptr += aux[-1] + 1 mtxs = {} rhss = {} ress = {} get_sub = mtx._get_submatrix for ir in six.iterkeys(mtxi): rhss[ir] = nm.zeros((nn[ir], ), dtype=nm.float64) ress[ir] = nm.zeros((nn[ir], ), dtype=nm.float64) for jr, idxr in enumerate(mtxslc_f[ir]): rhss[ir][mtxslc_s[ir][jr]] = rhs[idxr] for ic in six.iterkeys(mtxi): mtxid = '%s%s' % (ir, ic) mtxs[mtxid] = nm.zeros((nn[ir], nn[ic]), dtype=nm.float64) for jr, idxr in enumerate(mtxslc_f[ir]): for jc, idxc in enumerate(mtxslc_f[ic]): iir = mtxslc_s[ir][jr] iic = mtxslc_s[ic][jc] mtxs[mtxid][iir, iic] = get_sub(idxr, idxc).todense() self.orig_conf.function(ress, mtxs, rhss, nn) res = nm.zeros_like(rhs) for ir in six.iterkeys(mtxi): for jr, idxr in enumerate(mtxslc_f[ir]): res[idxr] = ress[ir][mtxslc_s[ir][jr]] return res
def test_ls_reuse(self): import numpy as nm from sfepy.solvers import Solver from sfepy.discrete.state import State self.problem.init_solvers(ls_conf=self.problem.solver_confs['d00']) nls = self.problem.get_nls() state0 = State(self.problem.equations.variables) state0.apply_ebc() vec0 = state0.get_reduced() self.problem.update_materials() rhs = nls.fun(vec0) mtx = nls.fun_grad(vec0) ok = True for name in ['i12', 'i01']: solver_conf = self.problem.solver_confs[name] method = solver_conf.get('method', '') precond = solver_conf.get('precond', '') name = ' '.join((solver_conf.name, solver_conf.kind, method, precond)).rstrip() self.report(name) try: ls = Solver.any_from_conf(solver_conf) except: self.report('skipped!') continue conf = ls.conf.copy() conf.force_reuse = True sol00 = ls(rhs, mtx=mtx, conf=conf) digest00 = ls.mtx_digest sol0 = ls(rhs, mtx=mtx) digest0 = ls.mtx_digest sol1 = ls(rhs, mtx=2 * mtx, conf=conf) digest1 = ls.mtx_digest sol2 = ls(rhs, mtx=2 * mtx) digest2 = ls.mtx_digest ls(rhs, mtx=2 * mtx) digest3 = ls.mtx_digest _ok = digest00 != digest0 self.report(digest00, '!=', digest0, ':', _ok) ok = ok and _ok _ok = digest0 == digest1 self.report(digest0, '==', digest1, ':', _ok) ok = ok and _ok _ok = digest1 != digest2 self.report(digest1, '!=', digest2, ':', _ok) ok = ok and _ok _ok = digest2[1] == digest3[1] self.report(digest2[1], '==', digest3[1], ':', _ok) ok = ok and _ok _ok = nm.allclose(sol00, sol0, atol=1e-12, rtol=0.0) self.report('sol00 == sol0:', _ok) ok = ok and _ok _ok = nm.allclose(sol0, sol1, atol=1e-12, rtol=0.0) self.report('sol0 == sol1:', _ok) ok = ok and _ok _ok = nm.allclose(sol0, 2 * sol2, atol=1e-12, rtol=0.0) self.report('sol0 == 2 * sol2:', _ok) ok = ok and _ok return ok
def __init__(self, conf, problem, **kwargs): from sfepy.discrete.state import State from sfepy.discrete import Problem from sfepy.base.conf import ProblemConf, get_standard_keywords from scipy.spatial import cKDTree as KDTree ScipyDirect.__init__(self, conf, **kwargs) # init subproblems pb_vars = problem.get_variables() # get "master" DofInfo and last index pb_adi_indx = problem.equations.variables.adi.indx self.adi_indx = pb_adi_indx.copy() last_indx = -1 for ii in self.adi_indx.itervalues(): last_indx = nm.max([last_indx, ii.stop]) # coupling variables self.cvars_to_pb = {} for jj in conf.coupling_variables: self.cvars_to_pb[jj] = [None, None] if jj in pb_vars.names: if pb_vars[jj].dual_var_name is not None: self.cvars_to_pb[jj][0] = -1 else: self.cvars_to_pb[jj][1] = -1 # init subproblems self.subpb = [] required, other = get_standard_keywords() master_prefix = output.get_output_prefix() for ii, ifname in enumerate(conf.others): sub_prefix = master_prefix[:-1] + '-sub%d:' % (ii + 1) output.set_output_prefix(sub_prefix) kwargs['master_problem'] = problem confi = ProblemConf.from_file(ifname, required, other, define_args=kwargs) pbi = Problem.from_conf(confi, init_equations=True) sti = State(pbi.equations.variables) pbi.equations.set_data(None, ignore_unknown=True) pbi.time_update() pbi.update_materials() sti.apply_ebc() pbi_vars = pbi.get_variables() output.set_output_prefix(master_prefix) self.subpb.append([pbi, sti, None]) # append "slave" DofInfo for jj in pbi_vars.names: if not(pbi_vars[jj].is_state()): continue didx = pbi.equations.variables.adi.indx[jj] ndof = didx.stop - didx.start if jj in self.adi_indx: if ndof != \ (self.adi_indx[jj].stop - self.adi_indx[jj].start): raise ValueError('DOFs do not match!') else: self.adi_indx.update({ jj: slice(last_indx, last_indx + ndof, None)}) last_indx += ndof for jj in conf.coupling_variables: if jj in pbi_vars.names: if pbi_vars[jj].dual_var_name is not None: self.cvars_to_pb[jj][0] = ii else: self.cvars_to_pb[jj][1] = ii self.subpb.append([problem, None, None]) self.cvars_to_pb_map = {} for varname, pbs in self.cvars_to_pb.iteritems(): # match field nodes coors = [] for ii in pbs: pbi = self.subpb[ii][0] pbi_vars = pbi.get_variables() fcoors = pbi_vars[varname].field.coors dc = nm.abs(nm.max(fcoors, axis=0)\ - nm.min(fcoors, axis=0)) ax = nm.where(dc > 1e-9)[0] coors.append(fcoors[:,ax]) if len(coors[0]) != len(coors[1]): raise ValueError('number of nodes does not match!') kdtree = KDTree(coors[0]) map_12 = kdtree.query(coors[1])[1] pbi1 = self.subpb[pbs[0]][0] pbi1_vars = pbi1.get_variables() eq_map_1 = pbi1_vars[varname].eq_map pbi2 = self.subpb[pbs[1]][0] pbi2_vars = pbi2.get_variables() eq_map_2 = pbi2_vars[varname].eq_map dpn = eq_map_2.dpn nnd = map_12.shape[0] map_12_nd = nm.zeros((nnd * dpn,), dtype=nm.int32) if dpn > 1: for ii in range(dpn): map_12_nd[ii::dpn] = map_12 * dpn + ii else: map_12_nd = map_12 idx = nm.where(eq_map_2.eq >= 0)[0] self.cvars_to_pb_map[varname] = eq_map_1.eq[map_12[idx]]
def __call__(self, rhs, x0=None, conf=None, eps_a=None, eps_r=None, i_max=None, mtx=None, status=None, **kwargs): from sfepy.discrete.state import State equations = self.context.equations aux_state = State(equations.variables) mtxi = {} for bk, bv in six.iteritems(conf.blocks): aux_state.fill(0.0) for jj in bv: idx = equations.variables.di.indx[jj] aux_state.vec[idx] = nm.nan aux_state.apply_ebc() vec0 = aux_state.get_reduced() mtxi[bk] = nm.where(nm.isnan(vec0))[0] mtxslc_s = {} mtxslc_f = {} nn = {} for ik, iv in six.iteritems(mtxi): ptr = 0 nn[ik] = len(iv) mtxslc_s[ik] = [] mtxslc_f[ik] = [] while ptr < nn[ik]: idx0 = iv[ptr:] idxrange = nm.arange(idx0[0], idx0[0] + len(idx0)) aux = nm.where(idx0 == idxrange)[0] mtxslc_s[ik].append(slice(ptr + aux[0], ptr + aux[-1] + 1)) mtxslc_f[ik].append(slice(idx0[aux][0], idx0[aux][-1] + 1)) ptr += aux[-1] + 1 mtxs = {} rhss = {} ress = {} get_sub = mtx._get_submatrix for ir in six.iterkeys(mtxi): rhss[ir] = nm.zeros((nn[ir],), dtype=nm.float64) ress[ir] = nm.zeros((nn[ir],), dtype=nm.float64) for jr, idxr in enumerate(mtxslc_f[ir]): rhss[ir][mtxslc_s[ir][jr]] = rhs[idxr] for ic in six.iterkeys(mtxi): mtxid = '%s%s' % (ir, ic) mtxs[mtxid] = nm.zeros((nn[ir], nn[ic]), dtype=nm.float64) for jr, idxr in enumerate(mtxslc_f[ir]): for jc, idxc in enumerate(mtxslc_f[ic]): iir = mtxslc_s[ir][jr] iic = mtxslc_s[ic][jc] mtxs[mtxid][iir, iic] = get_sub(idxr, idxc).todense() self.orig_conf.function(ress, mtxs, rhss, nn) res = nm.zeros_like(rhs) for ir in six.iterkeys(mtxi): for jr, idxr in enumerate(mtxslc_f[ir]): res[idxr] = ress[ir][mtxslc_s[ir][jr]] return res
def test_ls_reuse(self): import numpy as nm from sfepy.solvers import Solver from sfepy.discrete.state import State self.problem.init_solvers(ls_conf=self.problem.solver_confs['d00']) nls = self.problem.get_nls() state0 = State(self.problem.equations.variables) state0.apply_ebc() vec0 = state0.get_reduced() self.problem.update_materials() rhs = nls.fun(vec0) mtx = nls.fun_grad(vec0) ok = True for name in ['i12', 'i01']: solver_conf = self.problem.solver_confs[name] method = solver_conf.get('method', '') precond = solver_conf.get('precond', '') name = ' '.join((solver_conf.name, solver_conf.kind, method, precond)).rstrip() self.report(name) try: ls = Solver.any_from_conf(solver_conf) except: self.report('skipped!') continue conf = ls.conf.copy() conf.force_reuse = True sol00 = ls(rhs, mtx=mtx, conf=conf) digest00 = ls.mtx_digest sol0 = ls(rhs, mtx=mtx) digest0 = ls.mtx_digest sol1 = ls(rhs, mtx=2*mtx, conf=conf) digest1 = ls.mtx_digest sol2 = ls(rhs, mtx=2*mtx) digest2 = ls.mtx_digest ls(rhs, mtx=2*mtx) digest3 = ls.mtx_digest _ok = digest00 != digest0 self.report(digest00, '!=', digest0, ':', _ok); ok = ok and _ok _ok = digest0 == digest1 self.report(digest0, '==', digest1, ':', _ok); ok = ok and _ok _ok = digest1 != digest2 self.report(digest1, '!=', digest2, ':', _ok); ok = ok and _ok _ok = digest2[1] == digest3[1] self.report(digest2[1], '==', digest3[1], ':', _ok); ok = ok and _ok _ok = nm.allclose(sol00, sol0, atol=1e-12, rtol=0.0) self.report('sol00 == sol0:', _ok); ok = ok and _ok _ok = nm.allclose(sol0, sol1, atol=1e-12, rtol=0.0) self.report('sol0 == sol1:', _ok); ok = ok and _ok _ok = nm.allclose(sol0, 2 * sol2, atol=1e-12, rtol=0.0) self.report('sol0 == 2 * sol2:', _ok); ok = ok and _ok return ok
def create_state(self): return State(self.equations.variables)