示例#1
0
def generate_test_mesh_and_field():
  '''We define a 1D mesh with two regions:
  
    |<---A--->|<--B-->|
    0 1 2 3 4 5 6 7 8 9
  
  We then define a field "vec" with 3 subfields:
  subfield 'vec_a' is defined in region A
  subfield 'vec_b' is defined in region B
  subfield 'vec_ab' is defined in both region A and B'''

  dim = 1
  m = nmesh.generate_1d_mesh([(0.0, 5.0), (5.0, 9.0)], 0.5)

  el_a = ocaml.make_element("vec_a", [3], dim, 1)
  el_b = ocaml.make_element("vec_b", [3], dim, 1)
  el_ab = ocaml.make_element("vec_ab", [3], dim, 1)

  els = [ocaml.empty_element,
         ocaml.fuse_elements(el_ab, el_a), # region A
         ocaml.fuse_elements(el_ab, el_b)] # region B

  def enumerated_list(l): return zip(range(len(l)), l)

  mwe = ocaml.make_mwe("vec",
                       m.raw_mesh, 
                       enumerated_list(els),
                       [],
                       [(1, ['vec_ab', 'vec_a']),
                        (2, ['vec_ab', 'vec_b'])])

  # Create the field and set it to 0 everywhere
  field = ocaml.raw_make_field(mwe, [lambda x, y: 0.0], "", "")
  return m, field
示例#2
0
 def get_master(self):
     if self._master != None:
         return self._master
     else:
         assert self.vivified, "Cannot get master before vivification of field(%s)" % self.name
         self._master = field = ocaml.raw_make_field(self.mwe, [], "", "")
         return field
示例#3
0
 def get_master(self):
     if self._master != None:
         return self._master
     else:
         assert self.vivified, \
           "Cannot get master before vivification of field(%s)" % self.name
         self._master = field = ocaml.raw_make_field(self.mwe, [], "", "")
         return field
示例#4
0
elem_phi = ocaml.make_element("phi", [], 1, 1)  # scalar element

mwe_phi = ocaml.make_mwe("phi", raw_mesh, [(0, ocaml.empty_element), (1, elem_phi)], [])
mwe_dphi_dt = ocaml.mwe_sibling(mwe_phi, "dphi_dt", "dphi_dt/phi", [("phi", "dphi_dt")])
mwe_laplace_phi = ocaml.mwe_sibling(mwe_phi, "laplace_phi", "laplace_phi/phi", [("phi", "laplace_phi")])


def fun_phi0(dof_name, dof_pos):
    x = dof_pos[0] / 10.0
    # sx = math.sin((x-0.4)*2*3.1415926535)
    sx = math.sin((x - 0.4) * 2 * 3.1415926535)
    phi = math.exp(-sx * sx)
    return phi


field_phi0 = ocaml.raw_make_field(mwe_phi, [fun_phi0], "", "")
field_phi = ocaml.raw_make_field(mwe_phi, [], "", "")

eq_rhs = "dphi_dt <- laplace_phi;"

lam = make_linalg_machine(
    "lam_phi",
    mwes=[mwe_phi, mwe_dphi_dt, mwe_laplace_phi],
    vectors=[
        lam_vector(name="v_phi", mwe_name="phi"),
        lam_vector(name="v_dphi_dt", mwe_name="dphi_dt"),
        lam_vector(name="v_laplace_phi", mwe_name="laplace_phi"),
    ],
    operators=[
        lam_operator(
            "op_laplace",
    xpos = dof_pos[0]
    ypos = dof_pos[1]
    #xspos=math.sin(2*3.141592653589793*(2.0+xpos+5.0)/10.0)
    #yspos=math.cos(2*3.141592653589793*(3.0+ypos+5.0)/10.0)
    #r2=xspos-0.5*yspos
    #alpha=math.exp(-r2*r2)
    alpha=2*3.141592653589793*(2.0+xpos+5.0)/10.0
    alpha=3.141592653589793/4.0
    if ix==0:
        return 0.0
    elif ix==1:
        return math.sin(alpha)
    else:
        return -math.cos(alpha)

field_M0=ocaml.raw_make_field(mwe_M,[fun_M0],"","")
field_M=ocaml.raw_make_field(mwe_M,[],"","")
field_H_exch=ocaml.raw_make_field(mwe_H_exch,[],"","")

eq_rhs="""
%range i:3, j:3, k:3, p:3, q:3;

dM(i) <-
    1.2*eps(i,j,k)*M(j)*H_total(k)
  + (-0.03)*eps(i,j,k)*M(j)*eps(k,p,q)*M(p)*H_total(q)
  + (-1.0)*(M(j)*M(j)+(-1.0))*M(i);
""";

eq_H_total="""
%range j:3;
示例#6
0
def jT_lam(
        name="jT",
        sigma_el=1.0,  # electrical conductivity
        sigma_th=0.1,  # thermal conductivity
        c_heat=1.0 / 10.,  # heat capacity
        T_initial=300.0,
        mesh=None,
        ksp_tolerances={}):

    print "Debug: c_heat = %f, sigma_el=%f, sigma_th=%f" % (c_heat, sigma_el,
                                                            sigma_th)

    #sys.exit(0)
    intensive_params = ["TIME", "Phi_ext"]

    raw_mesh = mesh.raw_mesh
    dim = ocaml.mesh_dim(raw_mesh)

    def get_tol(name):
        if ksp_tolerances.has_key(name):
            ksp_tolerances[name]
        else:
            None

    elem_V = ocaml.make_element("V", [dim], dim, 1)
    elem_S = ocaml.make_element("S", [], dim, 1)

    def fun_outer_region(coords):

        if coords[0] < -499.9 or coords[0] > 499.9:
            return -2
        else:
            return -1

    def fun_T_initial(field, pos):
        #print ("SAMPLING field %s AT: %s" % (field,pos))
        return T_initial

    def fun_T_initial_debug(field, pos):
        print("SAMPLING field %s AT: %s" % (field, pos))
        # return T_initial
        x, y, z = pos
        if x < 0:
            return 300
        else:
            return 100

        return 0.0  #should not occur

    mwe_V = ocaml.make_mwe("V", raw_mesh, [(0, ocaml.empty_element),
                                           (1, elem_V)], [fun_outer_region])
    mwe_S = ocaml.make_mwe("S", raw_mesh, [(0, ocaml.empty_element),
                                           (1, elem_S)], [fun_outer_region])

    mwe_j = ocaml.mwe_sibling(mwe_V, "j", "j/V", [("V", "j")])
    mwe_phi = ocaml.mwe_sibling(mwe_S, "phi", "phi/S", [("S", "phi")])
    mwe_rho = ocaml.mwe_sibling(mwe_S, "rho", "rho/S", [("S", "rho")])

    mwe_T = ocaml.mwe_sibling(mwe_S, "T", "T/S", [("S", "T")])
    mwe_Laplace_T = ocaml.mwe_sibling(mwe_S, "Laplace_T", "Laplace_T/S",
                                      [("S", "Laplace_T")])
    mwe_dTdt = ocaml.mwe_sibling(mwe_S, "dTdt", "dTdt/S", [("S", "dTdt")])

    master_mwes_and_fields_by_name = {}

    master_mwes_and_fields_by_name["T"] = (mwe_T,
                                           ocaml.raw_make_field(
                                               mwe_T, [fun_T_initial], "", ""))
    master_mwes_and_fields_by_name["Laplace_T"] = (mwe_j,
                                                   ocaml.raw_make_field(
                                                       mwe_Laplace_T, [], "",
                                                       ""))
    master_mwes_and_fields_by_name["j"] = (mwe_j,
                                           ocaml.raw_make_field(
                                               mwe_j, [], "", ""))
    master_mwes_and_fields_by_name["phi"] = (mwe_phi,
                                             ocaml.raw_make_field(
                                                 mwe_phi, [], "", ""))
    master_mwes_and_fields_by_name["rho"] = (mwe_rho,
                                             ocaml.raw_make_field(
                                                 mwe_rho, [], "", ""))

    # Note that at present, SITE_WISE does not work properly with restricted vectors,
    # so we will have to set the heating voltage throughout the sample, and throw away
    # the values inside the bulk then.

    ccode_heating = """
if(have_phi) {
  if(COORDS(0)<0) {phi= 0.5*Phi_ext;}
  else            {phi= -0.5*Phi_ext;}
 }
"""

    # Note ad resistive heating: integrated power generation = U*I.
    # Local power generation = E*j. As j = sigma*E, we get p = j^2/sigma,
    # so the contribution to dT/dt is j^2/sigma.

    eq_dTdt = """%%range k:%d;
dTdt <- (%.8f)*Laplace_T + (%.8f)*j(k)*j(k);
""" % (dim, sigma_th / c_heat, 1.0 / (c_heat * sigma_el))

    print "DDD eq_dTdt: ", eq_dTdt

    lam_mwes = {
        "j": mwe_j,
        "phi": mwe_phi,
        "rho": mwe_rho,
        "T": mwe_T,
        "Laplace_T": mwe_Laplace_T,
        "dTdt": mwe_dTdt,
    }
    lam_vectors = {
        "v_j":
        nlam.lam_vector(name="v_j", mwe_name="j"),
        "v_phi":
        nlam.lam_vector(name="v_phi", mwe_name="phi"),
        "v_phi_boundary":
        nlam.lam_vector(name="v_phi_boundary",
                        mwe_name="phi",
                        restriction="phi[boundary=-2/*]"),
        "v_rho":
        nlam.lam_vector(name="v_rho", mwe_name="rho"),
        "v_T":
        nlam.lam_vector(name="v_T", mwe_name="T"),
        "v_Laplace_T":
        nlam.lam_vector(name="v_Laplace_T", mwe_name="Laplace_T"),
        "v_dTdt":
        nlam.lam_vector(name="v_dTdt", mwe_name="dTdt"),
    }

    lam_operators={\
        "op_j_phi":nlam.lam_operator("op_j_phi","j","phi",
                                     "%g*<j(k) || d/dxk phi>, k:%d" % (sigma_el,dim)),
        "op_Laplace_T":nlam.lam_operator("op_Laplace_T","Laplace_T","T",
                                         "-<d/dxk Laplace_T || d/dxk T>, k:%d" % dim
                                         ),
        # Tricky issue: we have DBC along the contacts and NBC everywhere else.
        # XXX REPAIR: LHS field should be named "rho".
        # XXX Can our "left field equals right field" syntax already cope with that?
        "op_laplace_DNBC":nlam.lam_operator("op_laplace_DNBC","phi","phi",
                                            """ -<d/dxk phi[vol] || d/dxk phi[vol]>
                                                -<d/dxk phi[boundary=-1/1] || d/dxk phi[vol]>
                                                -<d/dxk phi[boundary=-1/1] || d/dxk phi[boundary=-1/1]>
                                                -<d/dxk phi[vol] || d/dxk phi[boundary=-1/1]>
                                                ;phi[boundary=-2/*]=phi[boundary=-2/*], k:%d""" %dim),

        #"op_laplace_DNBC":nlam.lam_operator("op_laplace_DNBC","phi","phi",
        #                                    """ -<d/dxk phi || d/dxk phi>
        #                                        ;phi[boundary=-2/*]=phi[boundary=-2/*], k:%d""" %dim),


        "op_load_DBC":nlam.lam_operator("op_load_DBC","rho","phi",
                                        "<d/dxk rho || d/dxk phi[boundary=-2/*]>;(L||R)=(*||phi[boundary=-2/*]), k:%d" %dim),
        }

    lam_ksps = {
        "solve_laplace_DNBC":
        nlam.lam_ksp(
            name="solve_laplace_DNBC",
            matrix_name="op_laplace_DNBC",
            ksp_type="gmres",
            pc_type="ilu",
            initial_guess_nonzero=True,
            rtol=get_tol("DNBC.rtol"),
            atol=get_tol("DNBC.atol"),
            dtol=get_tol("DNBC.dtol"),
            maxits=get_tol("DNBC.maxits"),
        )
    }

    lam_local = {
        "local_dTdt":
        nlam.lam_local("local_dTdt",
                       field_mwes=["dTdt", "Laplace_T", "j"],
                       equation=eq_dTdt),
        "local_set_phi_heating":
        nlam.lam_local("local_set_phi_heating",
                       aux_args=intensive_params,
                       field_mwes=["phi"],
                       c_code=ccode_heating)
    }

    lam_jacobi = {
        "jacobian":
        nlam.lam_jplan(
            "jacobian",
            "dTdt",
            ["T", "Laplace_T", "j"],
            [
                [],
                [  # all contributions to d Laplace_T/dT
                    ("operator", "op_Laplace_T")
                ],
                [  # all contributions to dj/dT - none in this model.
                ]
            ],
            eq_dTdt)
    }

    lam_programs = {
        "update_dTdt":
        nlam.lam_program(
            "update_dTdt",
            commands=[
                ["TSTART", "update_dTdt"],
                ["GOSUB", "set_Laplace_T"],
                ["GOSUB", "set_j"],
                [
                    "SITE-WISE-IPARAMS", "local_dTdt",
                    ["v_dTdt", "v_Laplace_T", "v_j"], []
                ],
                # ["DEBUG","v_dTdt","v_dTdt",0], # seems okay!
                ["TSTOP", "update_dTdt"],
            ]),
        "set_Laplace_T":
        nlam.lam_program(
            "set_Laplace_T",
            commands=[
                ["TSTART", "Laplace_T"],
                ["SM*V", "op_Laplace_T", "v_T", "v_Laplace_T"],
                ["CFBOX", "Laplace_T", "v_Laplace_T"],
                # ["DEBUG","v_Laplace_T","v_Laplace_T",0],
                ["TSTOP", "Laplace_T"]
            ]),
        "set_j":
        nlam.lam_program(
            "set_j",
            commands=[
                ["TSTART", "j"],
                ["SITE-WISE-IPARAMS", "local_set_phi_heating", ["v_phi"], []],
                [
                    "PULL-FEM", "phi", "phi[boundary=-2/*]", "v_phi",
                    "v_phi_boundary"
                ],
                # ["DEBUG","v_phi_boundary","v_phi_boundary",0],
                ["SM*V", "op_load_DBC", "v_phi_boundary", "v_rho"],
                # ["DEBUG","v_rho","v_rho",0],
                ["SCALE", "v_phi", 0.0],
                ["SOLVE", "solve_laplace_DNBC", "v_rho", "v_phi"],
                [
                    "PUSH-FEM", "phi", "phi[boundary=-2/*]", "v_phi_boundary",
                    "v_phi"
                ],
                # ^ This is to add proper boundary values!
                ["SM*V", "op_j_phi", "v_phi", "v_j"],
                # ["DEBUG","v_phi","v_phi",0],
                # ["DEBUG","v_j","v_j",0],
                ["CFBOX", "j", "v_j"],
                ["TSTOP", "j"]
            ]),
        "execute_jplan":
        nlam.lam_program(
            "execute_jplan",
            commands=[["TSTART", "execute_jplan"], ["GOSUB", "set_Laplace_T"],
                      ["GOSUB", "set_j"],
                      ["JPLAN", "jacobian", ["v_T", "v_Laplace_T", "v_j"]],
                      ["TSTOP", "execute_jplan"]]),
        "rhs":
        nlam.lam_program(
            "rhs",
            args_fields=[["arg_dTdt", "dTdt"], ["arg_T",
                                                "T"]],  # [arg_name,mwe_name]
            commands=[
                ["TSTART", "rhs"],
                ["DISTRIB", "arg_T", "v_T"],
                # ["DEBUG","v_T","v_T",0],
                ["GOSUB", "update_dTdt"],
                ["COLLECT", "arg_dTdt", "v_dTdt"],
                # ["DEBUG","v_dTdt","v_dTdt",0],
                ["TSTOP", "rhs"]
            ]),
    }

    lam = nlam.make_linalg_machine(name,
                                   intensive_params=intensive_params,
                                   mwes=lam_mwes.values(),
                                   vectors=lam_vectors.values(),
                                   operators=lam_operators.values(),
                                   ksps=lam_ksps.values(),
                                   local_operations=lam_local.values(),
                                   jacobi_plans=lam_jacobi.values(),
                                   programs=lam_programs.values())

    return (lam, master_mwes_and_fields_by_name)
示例#7
0
max_order = 2
krylov_max = 100
max_it = 1000000

my_mesh = nmesh.load(mesh_filename)
(lam, master_mwes_and_fields_by_name) = jT_lam(
    mesh=my_mesh,
    sigma_el=su.of(sigma),  # electrical conductivity
    sigma_th=su.of(k),  # thermal conductivity
    c_heat=su.of(c_heat),  # heat capacity
    T_initial=su.of(T_initial),
)

(mwe_T, field_T) = master_mwes_and_fields_by_name['T']

sundialsbuffer_initial = ocaml.raw_make_field(mwe_T, [], "",
                                              "sundials_initial")
sundialsbuffer_final = ocaml.raw_make_field(mwe_T, [], "", "sundials_final")
sundialsbuffer_starting = ocaml.raw_make_field(mwe_T, [], "", "sundials_work")

ocaml.field_copy_into(field_T, sundialsbuffer_initial)
ocaml.field_copy_into(field_T, sundialsbuffer_starting)

(cvode,fun_timings)=ocaml.raw_make_linalg_machine_cvode(\
              lam, sundialsbuffer_starting,
              "jacobian","execute_jplan",
              "rhs",
              jacobi_same_nonzero_pattern,
              max_order,
              krylov_max,
              )
示例#8
0
文件: H.py 项目: fangohr/nmag-doc
def jT_lam(name="jT",
           sigma_el=1.0, # electrical conductivity
           sigma_th=0.1, # thermal conductivity
           c_heat=1.0/10.,# heat capacity
           T_initial=300.0,
           mesh=None,
           ksp_tolerances={}
           ):

    print "Debug: c_heat = %f, sigma_el=%f, sigma_th=%f" % (c_heat,sigma_el,sigma_th)

    #sys.exit(0)
    intensive_params=["TIME","Phi_ext"]

    raw_mesh=mesh.raw_mesh
    dim = ocaml.mesh_dim(raw_mesh)

    def get_tol(name):
        if ksp_tolerances.has_key(name):
            ksp_tolerances[name]
        else:
            None

    elem_V = ocaml.make_element("V", [dim], dim, 1)
    elem_S = ocaml.make_element("S", [], dim, 1)

    def fun_outer_region(coords):

        if coords[0]<-499.9 or coords[0]>499.9:
            return -2
        else:
            return -1

    def fun_T_initial(field,pos):
        #print ("SAMPLING field %s AT: %s" % (field,pos))
        return T_initial

    def fun_T_initial_debug(field,pos):
        print ("SAMPLING field %s AT: %s" % (field,pos))
        # return T_initial
	x,y,z=pos
	if x < 0: 
	       return 300
	else:
	       return 100
	    
        return 0.0 #should not occur

    

    mwe_V=ocaml.make_mwe("V",raw_mesh,[(0,ocaml.empty_element),(1,elem_V)],[fun_outer_region])
    mwe_S=ocaml.make_mwe("S",raw_mesh,[(0,ocaml.empty_element),(1,elem_S)],[fun_outer_region])

    mwe_j=ocaml.mwe_sibling(mwe_V,"j","j/V",[("V","j")])
    mwe_phi=ocaml.mwe_sibling(mwe_S,"phi","phi/S",[("S","phi")])
    mwe_rho=ocaml.mwe_sibling(mwe_S,"rho","rho/S",[("S","rho")])
    
    mwe_T=ocaml.mwe_sibling(mwe_S,"T","T/S",[("S","T")])
    mwe_Laplace_T=ocaml.mwe_sibling(mwe_S,"Laplace_T","Laplace_T/S",[("S","Laplace_T")])
    mwe_dTdt=ocaml.mwe_sibling(mwe_S,"dTdt","dTdt/S",[("S","dTdt")])

    master_mwes_and_fields_by_name={}

    master_mwes_and_fields_by_name["T"]=(mwe_T,ocaml.raw_make_field(mwe_T,[fun_T_initial],"",""))
    master_mwes_and_fields_by_name["Laplace_T"]=(mwe_j,ocaml.raw_make_field(mwe_Laplace_T,[],"",""))
    master_mwes_and_fields_by_name["j"]=(mwe_j,ocaml.raw_make_field(mwe_j,[],"",""))
    master_mwes_and_fields_by_name["phi"]=(mwe_phi,ocaml.raw_make_field(mwe_phi,[],"",""))
    master_mwes_and_fields_by_name["rho"]=(mwe_rho,ocaml.raw_make_field(mwe_rho,[],"",""))

    # Note that at present, SITE_WISE does not work properly with restricted vectors,
    # so we will have to set the heating voltage throughout the sample, and throw away
    # the values inside the bulk then.

    ccode_heating= """
if(have_phi) {
  if(COORDS(0)<0) {phi= 0.5*Phi_ext;}
  else            {phi= -0.5*Phi_ext;}
 }
"""

    # Note ad resistive heating: integrated power generation = U*I.
    # Local power generation = E*j. As j = sigma*E, we get p = j^2/sigma,
    # so the contribution to dT/dt is j^2/sigma.

    eq_dTdt="""%%range k:%d;
dTdt <- (%.8f)*Laplace_T + (%.8f)*j(k)*j(k);
""" % (dim,
       sigma_th/c_heat,
       1.0/(c_heat*sigma_el))


    print "DDD eq_dTdt: ",eq_dTdt

    lam_mwes={"j":mwe_j, "phi":mwe_phi, "rho":mwe_rho,
              "T":mwe_T, "Laplace_T":mwe_Laplace_T,
              "dTdt":mwe_dTdt,
              }
    lam_vectors={"v_j":nlam.lam_vector(name="v_j",mwe_name="j"),
                 "v_phi":nlam.lam_vector(name="v_phi",mwe_name="phi"),
                 "v_phi_boundary":nlam.lam_vector(name="v_phi_boundary",
                                                  mwe_name="phi",
                                                  restriction="phi[boundary=-2/*]"),
                 "v_rho":nlam.lam_vector(name="v_rho",mwe_name="rho"),
                 "v_T":nlam.lam_vector(name="v_T",mwe_name="T"),
                 "v_Laplace_T":nlam.lam_vector(name="v_Laplace_T",mwe_name="Laplace_T"),
                 "v_dTdt":nlam.lam_vector(name="v_dTdt",mwe_name="dTdt"),
                 }
    
    lam_operators={\
        "op_j_phi":nlam.lam_operator("op_j_phi","j","phi",
                                     "%g*<j(k) || d/dxk phi>, k:%d" % (sigma_el,dim)),
        "op_Laplace_T":nlam.lam_operator("op_Laplace_T","Laplace_T","T",
                                         "-<d/dxk Laplace_T || d/dxk T>, k:%d" % dim
                                         ),
        # Tricky issue: we have DBC along the contacts and NBC everywhere else.
        # XXX REPAIR: LHS field should be named "rho".
        # XXX Can our "left field equals right field" syntax already cope with that?
        "op_laplace_DNBC":nlam.lam_operator("op_laplace_DNBC","phi","phi",
                                            """ -<d/dxk phi[vol] || d/dxk phi[vol]>
                                                -<d/dxk phi[boundary=-1/1] || d/dxk phi[vol]>
                                                -<d/dxk phi[boundary=-1/1] || d/dxk phi[boundary=-1/1]>
                                                -<d/dxk phi[vol] || d/dxk phi[boundary=-1/1]>
                                                ;phi[boundary=-2/*]=phi[boundary=-2/*], k:%d""" %dim),

        #"op_laplace_DNBC":nlam.lam_operator("op_laplace_DNBC","phi","phi",
        #                                    """ -<d/dxk phi || d/dxk phi>
        #                                        ;phi[boundary=-2/*]=phi[boundary=-2/*], k:%d""" %dim),


        "op_load_DBC":nlam.lam_operator("op_load_DBC","rho","phi",
                                        "<d/dxk rho || d/dxk phi[boundary=-2/*]>;(L||R)=(*||phi[boundary=-2/*]), k:%d" %dim),
        }

    lam_ksps={"solve_laplace_DNBC":nlam.lam_ksp(name="solve_laplace_DNBC",
                                                matrix_name="op_laplace_DNBC",
                                                ksp_type="gmres", pc_type="ilu",
                                                initial_guess_nonzero=True,
                                                rtol=get_tol("DNBC.rtol"),
                                                atol=get_tol("DNBC.atol"),
                                                dtol=get_tol("DNBC.dtol"),
                                                maxits=get_tol("DNBC.maxits"),
                                                )
              }

    lam_local={"local_dTdt":nlam.lam_local("local_dTdt",
                                           field_mwes=["dTdt","Laplace_T","j"],
                                           equation=eq_dTdt),
               "local_set_phi_heating":nlam.lam_local("local_set_phi_heating",
                                                      aux_args=intensive_params,
                                                      field_mwes=["phi"],
                                                      c_code=ccode_heating)
               }

    lam_jacobi={"jacobian":nlam.lam_jplan("jacobian","dTdt",
                                          ["T","Laplace_T","j"],
                                          [[],
                                           [# all contributions to d Laplace_T/dT
                                            ("operator","op_Laplace_T")],
                                           [# all contributions to dj/dT - none in this model.
                                           ]],
                                          eq_dTdt
                                          )} 

    lam_programs={"update_dTdt":nlam.lam_program("update_dTdt",
                                                 commands=[["TSTART","update_dTdt"],
                                                           ["GOSUB", "set_Laplace_T"],
                                                           ["GOSUB", "set_j"],
                                                           ["SITE-WISE-IPARAMS", "local_dTdt",["v_dTdt","v_Laplace_T","v_j"],[]],
                                                           # ["DEBUG","v_dTdt","v_dTdt",0], # seems okay!
                                                           ["TSTOP", "update_dTdt"],
                                                           ]),
                  "set_Laplace_T":nlam.lam_program("set_Laplace_T",
                                                   commands=[["TSTART","Laplace_T"],
                                                             ["SM*V","op_Laplace_T","v_T","v_Laplace_T"],
                                                             ["CFBOX","Laplace_T","v_Laplace_T"],
                                                             # ["DEBUG","v_Laplace_T","v_Laplace_T",0],
                                                             ["TSTOP","Laplace_T"]]),
                  "set_j":nlam.lam_program("set_j",
                                           commands=[["TSTART","j"],
                                                     ["SITE-WISE-IPARAMS","local_set_phi_heating",["v_phi"],[]],
                                                     ["PULL-FEM","phi","phi[boundary=-2/*]","v_phi","v_phi_boundary"],
                                                     # ["DEBUG","v_phi_boundary","v_phi_boundary",0],
                                                     ["SM*V","op_load_DBC","v_phi_boundary","v_rho"],
                                                     # ["DEBUG","v_rho","v_rho",0],
                                                     ["SCALE","v_phi",0.0],
                                                     ["SOLVE","solve_laplace_DNBC","v_rho","v_phi"],
                                                     ["PUSH-FEM","phi","phi[boundary=-2/*]","v_phi_boundary","v_phi"],
                                                     # ^ This is to add proper boundary values!
                                                     ["SM*V","op_j_phi","v_phi","v_j"],
                                                     # ["DEBUG","v_phi","v_phi",0],
                                                     # ["DEBUG","v_j","v_j",0],
                                                     ["CFBOX","j","v_j"],
                                                     ["TSTOP","j"]]),
                  "execute_jplan":nlam.lam_program("execute_jplan",
                                                   commands=[["TSTART","execute_jplan"],
                                                             ["GOSUB", "set_Laplace_T"],
                                                             ["GOSUB", "set_j"],
                                                             ["JPLAN","jacobian",["v_T","v_Laplace_T","v_j"]],
                                                             ["TSTOP","execute_jplan"]]),
                  "rhs":nlam.lam_program("rhs",
                                         args_fields=[["arg_dTdt","dTdt"],["arg_T","T"]], # [arg_name,mwe_name]
                                         commands=[["TSTART","rhs"],
                                                   ["DISTRIB","arg_T","v_T"],
                                                   # ["DEBUG","v_T","v_T",0],
                                                   ["GOSUB", "update_dTdt"],
                                                   ["COLLECT","arg_dTdt","v_dTdt"],
                                                   # ["DEBUG","v_dTdt","v_dTdt",0],
                                                   ["TSTOP","rhs"]
                                                   ]),
                  }

    lam=nlam.make_linalg_machine(
        name,
        intensive_params=intensive_params,
        mwes=lam_mwes.values(),
        vectors=lam_vectors.values(),
        operators=lam_operators.values(),
        ksps=lam_ksps.values(),
        local_operations=lam_local.values(),
        jacobi_plans=lam_jacobi.values(),
        programs=lam_programs.values()
        )

    return (lam,master_mwes_and_fields_by_name)
示例#9
0
文件: H.py 项目: fangohr/nmag-doc
jacobi_same_nonzero_pattern=False
max_order=2
krylov_max=100
max_it=1000000

my_mesh=nmesh.load(mesh_filename)
(lam,master_mwes_and_fields_by_name) = jT_lam(mesh=my_mesh,
                                              sigma_el=su.of(sigma), # electrical conductivity
                                              sigma_th=su.of(k), # thermal conductivity
                                              c_heat=su.of(c_heat),# heat capacity
                                              T_initial=su.of(T_initial),
)

(mwe_T,field_T) = master_mwes_and_fields_by_name['T']

sundialsbuffer_initial = ocaml.raw_make_field(mwe_T,[],"","sundials_initial")
sundialsbuffer_final = ocaml.raw_make_field(mwe_T,[],"","sundials_final")
sundialsbuffer_starting = ocaml.raw_make_field(mwe_T,[],"","sundials_work")

ocaml.field_copy_into(field_T, sundialsbuffer_initial)
ocaml.field_copy_into(field_T, sundialsbuffer_starting)

(cvode,fun_timings)=ocaml.raw_make_linalg_machine_cvode(\
              lam, sundialsbuffer_starting,
              "jacobian","execute_jplan",
              "rhs",
              jacobi_same_nonzero_pattern,
              max_order,
              krylov_max,
              )
示例#10
0
def make_field(mwe, initial_values=None, petsc_name="", restriction=""):
    log.log(15, "About to create field from mwe XXX")
    iv = []
    if initial_values:
        iv = [initial_values]
    return ocaml.raw_make_field(mwe, iv, restriction, petsc_name)
示例#11
0
# Our differential operators:

diffop_laplace = ocaml.make_diffop("-<d/dxj drho_by_dt|sigma|d/dxj phi>, j:2")
diffop_grad_phi = ocaml.make_diffop("<J(k)|sigma|d/dxk phi>, k:2")

# Initial conductivity is spatially constant:


def fun_sigma0(dof_name_indices, position):
    return sigma0


# Later on, we will modify this field:

field_sigma = ocaml.raw_make_field(mwe_sigma, [fun_sigma0], "")  # petsc name - auto-generated if "".

print "field_sigma: ", field_sigma
print "Sigma at origin: ", ocaml.probe_field(field_sigma, "sigma", [0.0, 0.0])
sys.stdout.flush()

# Dirichlet Boundary Conditions on our sample:


def laplace_dbc(coords):
    if abs(coords[1]) > (2.5 - 0.05):
        return 1
    else:
        return 0

示例#12
0

import nfem
import sys,math,time
import ocaml #need this as long as we use ocaml.probe_field

mesh = ocaml.mesh_readfile("./debug-octa.mesh")

print "MESH: ",mesh

elem_m=ocaml.make_element("m_X",[3],3,1)
elem_H_demag=ocaml.make_element("H_demag",[3],3,1)

mwe_m=ocaml.make_mwe("mwe_m",mesh,[(1,elem_m)])
mwe_h=ocaml.make_mwe("mwe_h",mesh,[(1,elem_H_demag)])

def initial_m(dof,pos): # radially outward, zero at center
    ix=dof[1][0]
    return pos[ix]

field_m=ocaml.raw_make_field(mwe_m,[initial_m],"")

make_field_h=ocaml.ddd_demag_fun_3d("<S||d/dxj m_X(j)>, j:3",mwe_h,mwe_m)

field_h=make_field_h(field_m)

print field_h

sys.exit()

示例#13
0
文件: main.py 项目: fangohr/nmag-src
def make_field(mwe, initial_values=None, petsc_name="", restriction=""):
    log.log(15, "About to create field from mwe XXX")
    iv = []
    if initial_values:
        iv = [initial_values]
    return ocaml.raw_make_field(mwe, iv, restriction, petsc_name)
示例#14
0
import nfem
import sys, math, time
import ocaml  #need this as long as we use ocaml.probe_field

mesh = ocaml.mesh_readfile("./debug-octa.mesh")

print "MESH: ", mesh

elem_m = ocaml.make_element("m_X", [3], 3, 1)
elem_H_demag = ocaml.make_element("H_demag", [3], 3, 1)

mwe_m = ocaml.make_mwe("mwe_m", mesh, [(1, elem_m)])
mwe_h = ocaml.make_mwe("mwe_h", mesh, [(1, elem_H_demag)])


def initial_m(dof, pos):  # radially outward, zero at center
    ix = dof[1][0]
    return pos[ix]


field_m = ocaml.raw_make_field(mwe_m, [initial_m], "")

make_field_h = ocaml.ddd_demag_fun_3d("<S||d/dxj m_X(j)>, j:3", mwe_h, mwe_m)

field_h = make_field_h(field_m)

print field_h

sys.exit()
示例#15
0
                                           (1, elem_phi)], [])
mwe_dphi_dt = ocaml.mwe_sibling(mwe_phi, "dphi_dt", "dphi_dt/phi",
                                [("phi", "dphi_dt")])
mwe_laplace_phi = ocaml.mwe_sibling(mwe_phi, "laplace_phi", "laplace_phi/phi",
                                    [("phi", "laplace_phi")])


def fun_phi0(dof_name, dof_pos):
    x = dof_pos[0] / 10.0
    # sx = math.sin((x-0.4)*2*3.1415926535)
    sx = math.sin((x - 0.4) * 2 * 3.1415926535)
    phi = math.exp(-sx * sx)
    return phi


field_phi0 = ocaml.raw_make_field(mwe_phi, [fun_phi0], "", "")
field_phi = ocaml.raw_make_field(mwe_phi, [], "", "")

eq_rhs = "dphi_dt <- laplace_phi;"

lam = make_linalg_machine(
    "lam_phi",
    mwes=[mwe_phi, mwe_dphi_dt, mwe_laplace_phi],
    vectors=[
        lam_vector(name="v_phi", mwe_name="phi"),
        lam_vector(name="v_dphi_dt", mwe_name="dphi_dt"),
        lam_vector(name="v_laplace_phi", mwe_name="laplace_phi"),
    ],
    operators=[
        lam_operator("op_laplace",
                     "laplace_phi",
示例#16
0
diffop_laplace = ocaml.make_diffop("-<d/dxj drho_by_dt|sigma|d/dxj phi>, j:2")
diffop_grad_phi = ocaml.make_diffop("<J(k)|sigma|d/dxk phi>, k:2")

# Initial conductivity is spatially constant:


def fun_sigma0(dof_name_indices, position):
    return sigma0


# Later on, we will modify this field:

field_sigma = ocaml.raw_make_field(
    mwe_sigma,
    [fun_sigma0],
    ""  # petsc name - auto-generated if "".
)

print "field_sigma: ", field_sigma
print "Sigma at origin: ", ocaml.probe_field(field_sigma, "sigma", [0.0, 0.0])
sys.stdout.flush()

# Dirichlet Boundary Conditions on our sample:


def laplace_dbc(coords):
    if (abs(coords[1]) > (2.5 - 0.05)):
        return 1
    else:
        return 0
示例#17
0
    def _create_field(self, field_name, subfield_name=None, row=0):
        # This is the real subfield name
        full_field_name = build_full_field_name(field_name, subfield_name)

        # Now we get the data
        f = self.open_handler()
        root_data_fields = self.get_root_data_fields()

        dim = self.mesh.dim
        field_stuff = f.getNode(root_data_fields, field_name)
        field_shape = list(field_stuff.row[full_field_name].shape)[1:]

        # Get the sites where the subfield is defined (sites) and the
        # corresponding coordinates (ps) and values (vs)
        ps, vs, sites = self.get_field_array(field_name, subfield_name, row)

        # sites now contains the dof allocation for the subfield, i.e. in
        # which sites the subfield is defined.

        # We now want to build a numarray of one boolean value per each site
        # which says whether for that site the field is defined or not
        pointsregions = self.mesh.pointsregions
        num_sites = len(pointsregions)
        defined = numpy.ndarray(num_sites, dtype=numpy.bool)
        defined.fill(False)
        for site_where_defined in sites:
            defined[site_where_defined] = True

        # Run over all the sites and build a list of regions where the field
        # is undefined
        all_regions = range(1, self.mesh.numregions)
        regions_where_defined = range(1, self.mesh.numregions)
        for site in range(num_sites):
            if not defined[site]:
                regions_owning_this_site = pointsregions[site]
                for region in regions_owning_this_site:
                    if region in regions_where_defined:
                        regions_where_defined.remove(region)

        # Now we know in which regions of the mesh the field is defined
        logmsg("'%s' has been found in regions %s" %
               (full_field_name, regions_where_defined))

        # Consistency check: there musn't be a region where the field
        # is partially defined!
        logmsg("Now checking that there the field is always present...")
        for site in range(num_sites):
            field_should_be_defined_here = \
              (True in [rwd in pointsregions[site]
                        for rwd in regions_where_defined])
            # ^^^ True when this site belongs to one region which is listed
            # in 'regions_where_defined'
            if field_should_be_defined_here != defined[site]:
                logmsg("Inconsistency while checking the field definition "
                       "regions: site %d belongs to region %s, but the field "
                       "is defined in regions %s." %
                       (site, pointsregions[site], regions_where_defined))
                raise NmagUserError("The given file seems to be corrupt!"
                                    "Cannot proceed!")

        logmsg("Check successful: definition regions are %s" %
               regions_where_defined)

        logmsg("Creating a new element '%s' for the field" % full_field_name)
        element = ocaml.make_element(full_field_name, field_shape, dim,
                                     self.field_order)

        logmsg("Creating MWE")
        element_assoc = zip(regions_where_defined,
                            [element] * len(regions_where_defined))
        properties = zip(regions_where_defined,
                         [[full_field_name]] * len(regions_where_defined))
        mwe = ocaml.make_mwe(field_name, self.mesh.raw_mesh, element_assoc, [],
                             properties)

        logmsg("Creating the field")
        field = ocaml.raw_make_field(mwe, [], "", "")

        # We now try to understand how to map the data from file into the
        # newly created field
        metadata = ocaml.mwe_subfield_metadata(field, full_field_name)
        new_site_ids, new_pos, new_shape, new_site_vols = metadata
        num_new_sites = len(new_site_ids)
        if num_new_sites != len(sites):
            raise NmagUserError("The re-created field seems inconsistent "
                                "with the one saved to file. Number of "
                                "sites is %d for saved and %d for new field. "
                                "Cannot proceed!" % (num_sites, num_new_sites))

        # Check that the new field is binary compatible with the old one
        # this is really what we expect and allows us to set the field
        # by just passing a numarray as retrieved from the file
        need_map = False
        for i in range(num_new_sites):
            if new_site_ids[i] != sites[i]:
                need_map = True

        if need_map:
            raise NmagUserError("need_map=True, not implemented because this"
                                "was not expected to happen, anyway! Contact"
                                "Matteo ([email protected])")

        self.fields[full_field_name] = field
        timer1.start("x")
        ff.set_fielddata_from_numpyarray(field, full_field_name, vs)
        timer1.stop("x")
        return field
示例#18
0
    def _create_field(self, field_name, subfield_name=None, row=0):
        # This is the real subfield name
        full_field_name = build_full_field_name(field_name, subfield_name)

        # Now we get the data
        f = self.open_handler()
        root_data_fields = self.get_root_data_fields()

        dim = self.mesh.dim
        field_stuff = f.getNode(root_data_fields, field_name)
        field_shape = list(field_stuff.row[full_field_name].shape)[1:]

        # Get the sites where the subfield is defined (sites) and the
        # corresponding coordinates (ps) and values (vs)
        ps, vs, sites = self.get_field_array(field_name, subfield_name, row)

        # sites now contains the dof allocation for the subfield, i.e. in
        # which sites the subfield is defined.

        # We now want to build a numarray of one boolean value per each site
        # which says whether for that site the field is defined or not
        pointsregions = self.mesh.pointsregions
        num_sites = len(pointsregions)
        defined = numpy.ndarray(num_sites, dtype=numpy.bool)
        defined.fill(False)
        for site_where_defined in sites:
            defined[site_where_defined] = True

        # Run over all the sites and build a list of regions where the field
        # is undefined
        all_regions = range(1, self.mesh.numregions)
        regions_where_defined = range(1, self.mesh.numregions)
        for site in range(num_sites):
            if not defined[site]:
                regions_owning_this_site = pointsregions[site]
                for region in regions_owning_this_site:
                    if region in regions_where_defined:
                        regions_where_defined.remove(region)

        # Now we know in which regions of the mesh the field is defined
        logmsg("'%s' has been found in regions %s"
               % (full_field_name, regions_where_defined))

        # Consistency check: there musn't be a region where the field
        # is partially defined!
        logmsg("Now checking that there the field is always present...")
        for site in range(num_sites):
            field_should_be_defined_here = \
              (True in [rwd in pointsregions[site]
                        for rwd in regions_where_defined])
            # ^^^ True when this site belongs to one region which is listed
            # in 'regions_where_defined'
            if field_should_be_defined_here != defined[site]:
                logmsg("Inconsistency while checking the field definition "
                       "regions: site %d belongs to region %s, but the field "
                       "is defined in regions %s."
                       % (site, pointsregions[site], regions_where_defined))
                raise NmagUserError("The given file seems to be corrupt!"
                                    "Cannot proceed!")

        logmsg("Check successful: definition regions are %s"
               % regions_where_defined)

        logmsg("Creating a new element '%s' for the field" % full_field_name)
        element = ocaml.make_element(full_field_name, field_shape, dim,
                                     self.field_order)

        logmsg("Creating MWE")
        element_assoc = zip(regions_where_defined,
                            [element]*len(regions_where_defined))
        properties = zip(regions_where_defined,
                         [[full_field_name]]*len(regions_where_defined))
        mwe = ocaml.make_mwe(field_name,
                             self.mesh.raw_mesh,
                             element_assoc,
                             [],
                             properties)

        logmsg("Creating the field")
        field = ocaml.raw_make_field(mwe, [], "", "")

        # We now try to understand how to map the data from file into the
        # newly created field
        metadata = ocaml.mwe_subfield_metadata(field, full_field_name)
        new_site_ids, new_pos, new_shape, new_site_vols = metadata
        num_new_sites = len(new_site_ids)
        if num_new_sites != len(sites):
            raise NmagUserError("The re-created field seems inconsistent "
                                "with the one saved to file. Number of "
                                "sites is %d for saved and %d for new field. "
                                "Cannot proceed!" % (num_sites,num_new_sites))

        # Check that the new field is binary compatible with the old one
        # this is really what we expect and allows us to set the field
        # by just passing a numarray as retrieved from the file
        need_map = False
        for i in range(num_new_sites):
            if new_site_ids[i] != sites[i]:
                need_map = True

        if need_map:
            raise NmagUserError("need_map=True, not implemented because this"
                                "was not expected to happen, anyway! Contact"
                                "Matteo ([email protected])")

        self.fields[full_field_name] = field
        timer1.start("x")
        ff.set_fielddata_from_numpyarray(field, full_field_name, vs)
        timer1.stop("x")
        return field