Ejemplo n.º 1
0
def displayunit(offset, name, characterization, comment):  # {{{

    #take care of name
    if len(name) > 23:
        name = "%s..." % name[:20]

    #take care of characterization
    if m.strcmp(characterization, "''") or m.strcmp(
            characterization, '""') or m.strcmpi(characterization, 'nan'):
        characterization = "N/A"

    if len(characterization) > 15:
        characterization = "%s..." % characterization[:12]

    #print
    if not comment:
        string = "%s%-23s: %-15s" % (offset, name, characterization)
    else:
        if isinstance(comment, (str, unicode)):
            string = "%s%-23s: %-15s -- %s" % (offset, name, characterization,
                                               comment)
        elif isinstance(comment, list):
            string = "%s%-23s: %-15s -- %s" % (offset, name, characterization,
                                               comment[0])
            for commenti in comment:
                string += "\n%s%-23s  %-15s    %s" % (offset, '', '', commenti)
        else:
            raise RuntimeError(
                "fielddisplay error message: format for comment not supported yet"
            )

    return string
Ejemplo n.º 2
0
def FormatToCode(format):  # {{{
    """
	This routine takes the format string, and hardcodes it into an integer, which 
	is passed along the record, in order to identify the nature of the dataset being 
	sent.
	"""

    if m.strcmpi(format, 'Boolean'):
        code = 1
    elif m.strcmpi(format, 'Integer'):
        code = 2
    elif m.strcmpi(format, 'Double'):
        code = 3
    elif m.strcmpi(format, 'String'):
        code = 4
    elif m.strcmpi(format, 'BooleanMat'):
        code = 5
    elif m.strcmpi(format, 'IntMat'):
        code = 6
    elif m.strcmpi(format, 'DoubleMat'):
        code = 7
    elif m.strcmpi(format, 'MatArray'):
        code = 8
    elif m.strcmpi(format, 'StringArray'):
        code = 9
    elif m.strcmpi(format, 'CompressedMat'):
        code = 10
    else:
        raise InputError(
            'FormatToCode error message: data type not supported yet!')

    return code
Ejemplo n.º 3
0
def list_display(offset, name, field, comment):  # {{{

    #initialization
    if isinstance(field, list):
        sbeg = '['
        send = ']'
    elif isinstance(field, tuple):
        sbeg = '('
        send = ')'
    string = sbeg

    #go through the cell and fill string
    if len(field) < 5:
        for fieldi in field:
            if isinstance(fieldi, (str, unicode)):
                string += "'%s'," % fieldi
            elif isinstance(fieldi, (bool, int, long, float)):
                string += "%s," % str(fieldi)
            else:
                string = sbeg
                break

    if m.strcmp(string, sbeg):
        string = "%s%dx1%s" % (sbeg, len(field), send)
    else:
        string = string[:-1] + send

    #call displayunit
    return displayunit(offset, name, string, comment)
Ejemplo n.º 4
0
    def checkconsistency(self, md, solution, analyses):  # {{{

        md = checkfield(md, 'fieldname', 'mesh.x', 'NaN', 1, 'Inf', 1, 'size',
                        [md.mesh.numberofvertices])
        md = checkfield(md, 'fieldname', 'mesh.y', 'NaN', 1, 'Inf', 1, 'size',
                        [md.mesh.numberofvertices])
        md = checkfield(md, 'fieldname', 'mesh.z', 'NaN', 1, 'Inf', 1, 'size',
                        [md.mesh.numberofvertices])
        md = checkfield(md, 'fieldname', 'mesh.elements', 'NaN', 1, 'Inf', 1,
                        '>', 0, 'values',
                        np.arange(1, md.mesh.numberofvertices + 1))
        md = checkfield(md, 'fieldname', 'mesh.elements', 'size',
                        [md.mesh.numberofelements, 6])
        if np.any(
                np.logical_not(
                    m.ismember(np.arange(1, md.mesh.numberofvertices + 1),
                               md.mesh.elements))):
            md.checkmessage(
                "orphan nodes have been found. Check the mesh3dprisms outline")
        md = checkfield(md, 'fieldname', 'mesh.numberoflayers', '>=', 0)
        md = checkfield(md, 'fieldname', 'mesh.numberofelements', '>', 0)
        md = checkfield(md, 'fieldname', 'mesh.numberofvertices', '>', 0)
        md = checkfield(md, 'fieldname', 'mesh.vertexonbase', 'size',
                        [md.mesh.numberofvertices], 'values', [0, 1])
        md = checkfield(md, 'fieldname', 'mesh.vertexonsurface', 'size',
                        [md.mesh.numberofvertices], 'values', [0, 1])
        md = checkfield(
            md, 'fieldname', 'mesh.average_vertex_connectivity', '>=', 24,
            'message',
            "'mesh.average_vertex_connectivity' should be at least 24 in 3d")

        return md
Ejemplo n.º 5
0
    def Download(self, dirname, filelist):  # {{{

        if m.ispc():
            #do nothing
            return

        #copy files from cluster to current directory
        directory = '%s/%s/' % (self.executionpath, dirname)
        issmscpin(self.hostname, self.login, self.port, directory, filelist)
Ejemplo n.º 6
0
    def __init__(self, *args):  # {{{
        self._currentstep = 0
        self.repository = './'
        self.prefix = 'model.'
        self.trunkprefix = ''
        self.steps = []
        self.requestedsteps = [0]

        #process options
        options = pairoptions.pairoptions(*args)

        #Get prefix
        prefix = options.getfieldvalue('prefix', 'model.')
        if not isinstance(prefix, (str, unicode)):
            raise TypeError("prefix is not a string")
        if not m.strcmp(prefix, prefix.strip()) or len(prefix.split()) > 1:
            raise TypeError("prefix should not have any white space")
        self.prefix = prefix

        #Get repository
        repository = options.getfieldvalue('repository', './')
        if not isinstance(repository, (str, unicode)):
            raise TypeError("repository is not a string")
        if not os.path.isdir(repository):
            raise IOError("Directory '%s' not found" % repository)
        self.repository = repository

        #Get steps
        self.requestedsteps = options.getfieldvalue('steps', [0])

        #Get trunk prefix (only if provided by user)
        if options.exist('trunkprefix'):
            trunkprefix = options.getfieldvalue('trunkprefix', '')
            if not isinstance(trunkprefix, (str, unicode)):
                raise TypeError("trunkprefix is not a string")
            if not m.strcmp(trunkprefix, trunkprefix.strip()) or len(
                    trunkprefix.split()) > 1:
                raise TypeError("trunkprefix should not have any white space")
            self.trunkprefix = trunkprefix
Ejemplo n.º 7
0
    def BuildKrigingQueueScript(self, modelname, solution, io_gather,
                                isvalgrind, isgprof):  # {{{

        #write queuing script
        if not m.ispc():

            fid = open(modelname + '.queue', 'w')
            fid.write('#!/bin/sh\n')
            if not isvalgrind:
                if self.interactive:
                    fid.write('srun -np %i %s/kriging.exe %s/%s %s ' %
                              (self.np, self.codepath, self.executionpath,
                               modelname, modelname))
                else:
                    fid.write(
                        'srun -np %i %s/kriging.exe %s/%s %s 2> %s.errlog >%s.outlog '
                        % (self.np, self.codepath, self.executionpath,
                           modelname, modelname, modelname, modelname))
            elif isgprof:
                fid.write('\n gprof %s/kriging.exe gmon.out > %s.performance'
                          & (self.codepath, modelname))
            else:
                #Add --gen-suppressions=all to get suppression lines
                fid.write('LD_PRELOAD=%s \\\n' % self.valgrindlib)
                fid.write('mpiexec -np %i %s --leak-check=full --suppressions=%s %s/kriging.exe %s/%s %s 2> %s.errlog >%s.outlog ' % \
                  (self.np,self.valgrind,self.valgrindsup,self.codepath,self.executionpath,modelname,modelname,modelname,modelname))
            if not io_gather:  #concatenate the output files:
                fid.write('\ncat %s.outbin.* > %s.outbin' %
                          (modelname, modelname))
            fid.close()

        else:  # Windows

            fid = open(modelname + '.bat', 'w')
            fid.write('@echo off\n')
            if self.interactive:
                fid.write('"%s/issm.exe" %s "%s/%s" %s ' %
                          (self.codepath, solution, self.executionpath,
                           modelname, modelname))
            else:
                fid.write('"%s/issm.exe" %s "%s/%s" %s 2> %s.errlog >%s.outlog' % \
                  (self.codepath,solution,self.executionpath,modelname,modelname,modelname,modelname))
            fid.close()

        #in interactive mode, create a run file, and errlog and outlog file
        if self.interactive:
            fid = open(modelname + '.errlog', 'w')
            fid.close()
            fid = open(modelname + '.outlog', 'w')
            fid.close()
Ejemplo n.º 8
0
	def checkconsistency(self,md,solution,analyses): # {{{
		md = checkfield(md,'fieldname','mask.groundedice_levelset','size',[md.mesh.numberofvertices])
		md = checkfield(md,'fieldname','mask.ice_levelset'        ,'size',[md.mesh.numberofvertices])
		md = checkfield(md,'fieldname','mask.ocean_levelset','size',[md.mesh.numberofvertices])
		md = checkfield(md,'fieldname','mask.land_levelset','size',[md.mesh.numberofvertices])
		isice=(md.mask.ice_levelset<=0)
		if sum(isice)==0:
			print('no ice present in the domain')

		if max(md.mask.ice_levelset)<0:
			print('no ice front provided')

		elements=md.mesh.elements-1; elements=elements.astype(np.int32, copy=False);
		icefront=np.sum(md.mask.ice_levelset[elements]==0,axis=1)
		if (max(icefront)==3 & m.strcmp(md.mesh.elementtype(),'Tria')) or (max(icefront==6) & m.strcmp(md.mesh.elementtype(),'Penta')):
			raise RuntimeError('At least one element has all nodes on ice front, change md.mask.ice_levelset to fix it')

		return md
Ejemplo n.º 9
0
    def BuildQueueScript(self, dirname, modelname, solution, io_gather,
                         isvalgrind, isgprof, isdakota,
                         isoceancoupling):  # {{{

        executable = 'issm.exe'
        if isdakota:
            version = IssmConfig('_DAKOTA_VERSION_')[0:2]
            version = float(version)
            if version >= 6:
                executable = 'issm_dakota.exe'
        if isoceancoupling:
            executable = 'issm_ocean.exe'

        #write queuing script
        if not m.ispc():

            fid = open(modelname + '.queue', 'w')
            #fid.write('#!/bin/bash -l\n\n')
            #fid.write('#SBATCH -N 1\n')
            #fid.write('#SBATCH -J my_job\n')
            #fid.write('#SBATCH --export=ALL\n\n')
            fid.write('#!/bin/bash\n')
            fid.write('#SBATCH --nodes=%i\n' % 1)  #self.np)
            fid.write('#SBATCH --ntasks=%i\n' % 1)
            fid.write('#SBATCH --ntasks-per-node=%i\n' % 1)
            fid.write('#SBATCH --cpus-per-task=%i\n' % 1)
            fid.write('#SBATCH --job-name=%s\n' % modelname)
            #fid.write('#SBATCH -t %i\n',cluster.time*60);
            fid.write('#SBATCH -p smp \n')
            fid.write('#SBATCH -o %s.outlog \n' % modelname)
            fid.write('#SBATCH -e %s.errlog \n' % modelname)
            fid.write('#SBATCH --get-user-env \n')
            #fid.write('##  Enlarge the stacksize. OpenMP-codes usually need a large stack. \n')
            #fid.write('ulimit -s unlimited\n')
            #fid.write('## This binds each thread to one core \n')
            #fid.write('export OMP_PROC_BIND=TRUE \n')
            #fid.write('## Number of threads as given by -c / --cpus-per-task \n')
            #fid.write('export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK \n')
            #fid.write('## This code snippet checks the task and thread distribution on the cores. \n')
            #fid.write('srun /global/AWIsoft/xthi/xthi.intel | sort -n -k4,4 -k6,6 > xthi.log \n')
            pth = self.executionpath + '/' + dirname
            fid.write('srun %s/issm.exe %s %s %s > %s.log\n' %
                      (self.codepath, solution, pth, modelname, modelname))
Ejemplo n.º 10
0
    def perform(self, string):  # {{{

        bool = False

        #Some checks
        if not isinstance(string, (str, unicode)):
            raise TypeError("Step provided should be a string")
        if not m.strcmp(string, string.strip()) or len(string.split()) > 1:
            raise TypeError("Step provided should not have any white space")
        if self._currentstep > 0 and string in [
                step['string'] for step in self.steps
        ]:
            raise RuntimeError("Step '%s' already present. Change name" %
                               string)

        #Add step
        self.steps.append(OrderedDict())
        self.steps[-1]['id'] = len(self.steps)
        self.steps[-1]['string'] = string
        self._currentstep += 1

        #if requestedsteps = 0, print all steps in self
        if 0 in self.requestedsteps:
            if self._currentstep == 1:
                print "   prefix: %s" % self.prefix
            print "   step #%i : %s" % (
                self.steps[self._currentstep - 1]['id'],
                self.steps[self._currentstep - 1]['string'])

        #Ok, now if _currentstep is a member of steps, return true
        if self._currentstep in self.requestedsteps:
            print "\n   step #%i : %s\n" % (
                self.steps[self._currentstep - 1]['id'],
                self.steps[self._currentstep - 1]['string'])
            bool = True

        #assign self back to calling workspace
        # (no need, since Python modifies class instance directly)

        return bool
Ejemplo n.º 11
0
    def checkconsistency(self, md, solution, analyses):  # {{{

        #Early return
        if ('StressbalanceAnalysis' not in analyses
                and 'StressbalanceSIAAnalysis'
                not in analyses) or (solution == 'TransientSolution'
                                     and not md.transient.isstressbalance):
            return md

        md = checkfield(md, 'fieldname', 'flowequation.isSIA', 'numel', [1],
                        'values', [0, 1])
        md = checkfield(md, 'fieldname', 'flowequation.isSSA', 'numel', [1],
                        'values', [0, 1])
        md = checkfield(md, 'fieldname', 'flowequation.isL1L2', 'numel', [1],
                        'values', [0, 1])
        md = checkfield(md, 'fieldname', 'flowequation.isHO', 'numel', [1],
                        'values', [0, 1])
        md = checkfield(md, 'fieldname', 'flowequation.isFS', 'numel', [1],
                        'values', [0, 1])
        md = checkfield(
            md, 'fieldname', 'flowequation.fe_SSA', 'values',
            ['P1', 'P1bubble', 'P1bubblecondensed', 'P2', 'P2bubble'])
        md = checkfield(md, 'fieldname', 'flowequation.fe_HO', 'values', [
            'P1', 'P1bubble', 'P1bubblecondensed', 'P1xP2', 'P2xP1', 'P2',
            'P2bubble', 'P1xP3', 'P2xP4'
        ])
        md = checkfield(md, 'fieldname', 'flowequation.fe_FS', 'values', [
            'P1P1', 'P1P1GLS', 'MINIcondensed', 'MINI', 'TaylorHood',
            'XTaylorHood', 'OneLayerP4z', 'CrouzeixRaviart'
        ])
        md = checkfield(md, 'fieldname', 'flowequation.borderSSA', 'size',
                        [md.mesh.numberofvertices], 'values', [0, 1])
        md = checkfield(md, 'fieldname', 'flowequation.borderHO', 'size',
                        [md.mesh.numberofvertices], 'values', [0, 1])
        md = checkfield(md, 'fieldname', 'flowequation.borderFS', 'size',
                        [md.mesh.numberofvertices], 'values', [0, 1])
        md = checkfield(md, 'fieldname', 'flowequation.augmented_lagrangian_r',
                        'numel', [1], '>', 0.)
        md = checkfield(md, 'fieldname',
                        'flowequation.augmented_lagrangian_rhop', 'numel', [1],
                        '>', 0.)
        md = checkfield(md, 'fieldname',
                        'flowequation.augmented_lagrangian_rlambda', 'numel',
                        [1], '>', 0.)
        md = checkfield(md, 'fieldname',
                        'flowequation.augmented_lagrangian_rholambda', 'numel',
                        [1], '>', 0.)
        md = checkfield(md, 'fieldname', 'flowequation.XTH_theta', 'numel',
                        [1], '>=', 0., '<', .5)
        if m.strcmp(md.mesh.domaintype(), '2Dhorizontal'):
            md = checkfield(md, 'fieldname', 'flowequation.vertex_equation',
                            'size', [md.mesh.numberofvertices], 'values',
                            [1, 2])
            md = checkfield(md, 'fieldname', 'flowequation.element_equation',
                            'size', [md.mesh.numberofelements], 'values',
                            [1, 2])
        elif m.strcmp(md.mesh.domaintype(), '3D'):
            md = checkfield(md, 'fieldname', 'flowequation.vertex_equation',
                            'size', [md.mesh.numberofvertices], 'values',
                            np.arange(0, 8 + 1))
            md = checkfield(md, 'fieldname', 'flowequation.element_equation',
                            'size', [md.mesh.numberofelements], 'values',
                            np.arange(0, 8 + 1))
        else:
            raise RuntimeError('mesh type not supported yet')
        if not (self.isSIA or self.isSSA or self.isL1L2 or self.isHO
                or self.isFS):
            md.checkmessage("no element types set for this model")

        if 'StressbalanceSIAAnalysis' in analyses:
            if any(self.element_equation == 1):
                if np.any(
                        np.logical_and(self.vertex_equation,
                                       md.mask.groundedice_levelset)):
                    print "\n !!! Warning: SIA's model is not consistent on ice shelves !!!\n"

        return md
Ejemplo n.º 12
0
def ComputeHessian(index, x, y, field, type):
    """
	COMPUTEHESSIAN - compute hessian matrix from a field

	   Compute the hessian matrix of a given field
	   return the three components Hxx Hxy Hyy
	   for each element or each node

	   Usage:
	      hessian=ComputeHessian(index,x,y,field,type)

	   Example:
	      hessian=ComputeHessian(md.mesh.elements,md.mesh.x,md.mesh.y,md.inversion.vel_obs,'node')
	"""

    #some variables
    numberofnodes = np.size(x)
    numberofelements = np.size(index, axis=0)

    #some checks
    if np.size(field) != numberofnodes and np.size(field) != numberofelements:
        raise TypeError(
            "ComputeHessian error message: the given field size not supported yet"
        )
    if not m.strcmpi(type, 'node') and not m.strcmpi(type, 'element'):
        raise TypeError(
            "ComputeHessian error message: only 'node' or 'element' type supported yet"
        )

    #initialization
    line = index.reshape(-1, order='F')
    linesize = 3 * numberofelements

    #get areas and nodal functions coefficients N(x,y)=alpha x + beta y + gamma
    [alpha, beta, dum] = GetNodalFunctionsCoeff(index, x, y)
    areas = GetAreas(index, x, y)

    #compute weights that hold the volume of all the element holding the node i
    weights = m.sparse(line, np.ones((linesize, 1)),
                       np.tile(areas.reshape(-1, ), (3, 1)), numberofnodes, 1)

    #compute field on nodes if on elements
    if np.size(field, axis=0) == numberofelements:
        field = m.sparse(line, np.ones(
            (linesize, 1)), np.tile(areas * field,
                                    (3, 1)), numberofnodes, 1) / weights

    #Compute gradient for each element
    grad_elx = np.sum(field[index - 1, 0] * alpha, axis=1)
    grad_ely = np.sum(field[index - 1, 0] * beta, axis=1)

    #Compute gradient for each node (average of the elements around)
    gradx = m.sparse(line, np.ones((linesize, 1)),
                     np.tile((areas * grad_elx).reshape(-1, ), (3, 1)),
                     numberofnodes, 1)
    grady = m.sparse(line, np.ones((linesize, 1)),
                     np.tile((areas * grad_ely).reshape(-1, ), (3, 1)),
                     numberofnodes, 1)
    gradx = gradx / weights
    grady = grady / weights

    #Compute hessian for each element
    hessian = np.vstack(
        (np.sum(gradx[index - 1, 0] * alpha, axis=1).reshape(-1, ),
         np.sum(grady[index - 1, 0] * alpha, axis=1).reshape(-1, ),
         np.sum(grady[index - 1, 0] * beta, axis=1).reshape(-1, ))).T

    if m.strcmpi(type, 'node'):
        #Compute Hessian on the nodes (average of the elements around)
        hessian = np.hstack(
            (m.sparse(line, np.ones((linesize, 1)),
                      np.tile((areas * hessian[:, 0]).reshape(-1, ),
                              (3, 1)), numberofnodes, 1) / weights,
             m.sparse(line, np.ones((linesize, 1)),
                      np.tile((areas * hessian[:, 1]).reshape(-1, ),
                              (3, 1)), numberofnodes, 1) / weights,
             m.sparse(line, np.ones((linesize, 1)),
                      np.tile((areas * hessian[:, 2]).reshape(-1, ),
                              (3, 1)), numberofnodes, 1) / weights))

    return hessian
Ejemplo n.º 13
0
    def BuildQueueScript(self, dirname, modelname, solution, io_gather,
                         isvalgrind, isgprof, isdakota,
                         isoceancoupling):  # {{{

        executable = 'issm.exe'
        if isdakota:
            version = IssmConfig('_DAKOTA_VERSION_')[0:2]
            version = float(version)
            if version >= 6:
                executable = 'issm_dakota.exe'
        if isoceancoupling:
            executable = 'issm_ocean.exe'

        #write queuing script
        if not m.ispc():

            fid = open(modelname + '.queue', 'w')
            fid.write('#!/bin/sh\n')
            if not isvalgrind:
                if self.interactive:
                    if IssmConfig('_HAVE_MPI_')[0]:
                        fid.write(
                            'mpiexec -np %i %s/%s %s %s/%s %s ' %
                            (self.np, self.codepath, executable, solution,
                             self.executionpath, dirname, modelname))
                    else:
                        fid.write('%s/%s %s %s/%s %s ' %
                                  (self.codepath, executable, solution,
                                   self.executionpath, dirname, modelname))
                else:
                    if IssmConfig('_HAVE_MPI_')[0]:
                        fid.write(
                            'mpiexec -np %i %s/%s %s %s/%s %s 2> %s.errlog >%s.outlog '
                            % (self.np, self.codepath, executable, solution,
                               self.executionpath, dirname, modelname,
                               modelname, modelname))
                    else:
                        fid.write(
                            '%s/%s %s %s/%s %s 2> %s.errlog >%s.outlog ' %
                            (self.codepath, executable, solution,
                             self.executionpath, dirname, modelname, modelname,
                             modelname))
            elif isgprof:
                fid.write('\n gprof %s/%s gmon.out > %s.performance' %
                          (self.codepath, executable, modelname))
            else:
                #Add --gen-suppressions=all to get suppression lines
                fid.write('LD_PRELOAD=%s \\\n' % self.valgrindlib)
                if IssmConfig('_HAVE_MPI_')[0]:
                    fid.write('mpiexec -np %i %s --leak-check=full --suppressions=%s %s/%s %s %s/%s %s 2> %s.errlog >%s.outlog ' % \
                      (self.np,self.valgrind,self.valgrindsup,self.codepath,executable,solution,self.executionpath,dirname,modelname,modelname,modelname))
                else:
                    fid.write('%s --leak-check=full --suppressions=%s %s/%s %s %s/%s %s 2> %s.errlog >%s.outlog ' % \
                      (self.valgrind,self.valgrindsup,self.codepath,executable,solution,self.executionpath,dirname,modelname,modelname,modelname))

            if not io_gather:  #concatenate the output files:
                fid.write('\ncat %s.outbin.* > %s.outbin' %
                          (modelname, modelname))
            fid.close()

        else:  # Windows

            fid = open(modelname + '.bat', 'w')
            fid.write('@echo off\n')
            if self.interactive:
                fid.write('"%s/%s" %s "%s/%s" %s ' %
                          (self.codepath, executable, solution,
                           self.executionpath, dirname, modelname))
            else:
                fid.write('"%s/%s" %s "%s/%s" %s 2> %s.errlog >%s.outlog' % \
                 (self.codepath,executable,solution,self.executionpath,dirname,modelname,modelname,modelname))
            fid.close()

        #in interactive mode, create a run file, and errlog and outlog file
        if self.interactive:
            fid = open(modelname + '.errlog', 'w')
            fid.close()
            fid = open(modelname + '.outlog', 'w')
            fid.close()
Ejemplo n.º 14
0
def loadresultsfromdisk(md, filename):
    """
	LOADRESULTSFROMDISK - load results of solution sequence from disk file "filename"            
 
	   Usage:
	      md=loadresultsfromdisk(md=False,filename=False);
	"""

    #check number of inputs/outputs
    if not md or not filename:
        raise ValueError("loadresultsfromdisk: error message.")

    if not md.qmu.isdakota:

        #Check that file exists
        if not os.path.exists(filename):
            raise OSError("binary file '%s' not found." % filename)

        #initialize md.results if not a structure yet
        if not isinstance(md.results, results):
            md.results = results()

        #load results onto model
        structure = parseresultsfromdisk(md, filename,
                                         not md.settings.io_gather)
        if not len(structure):
            raise RuntimeError(
                "No result found in binary file '%s'. Check for solution crash."
                % filename)
        setattr(md.results, structure[0].SolutionType, structure)

        #recover solution_type from results
        md.private.solution = structure[0].SolutionType

        #read log files onto fields
        if os.path.exists(md.miscellaneous.name + '.errlog'):
            with open(md.miscellaneous.name + '.errlog', 'r') as f:
                setattr(
                    getattr(md.results, structure[0].SolutionType)[0],
                    'errlog', [line[:-1] for line in f])
        else:
            setattr(
                getattr(md.results, structure[0].SolutionType)[0], 'errlog',
                [])

        if os.path.exists(md.miscellaneous.name + '.outlog'):
            with open(md.miscellaneous.name + '.outlog', 'r') as f:
                setattr(
                    getattr(md.results, structure[0].SolutionType)[0],
                    'outlog', [line[:-1] for line in f])
        else:
            setattr(
                getattr(md.results, structure[0].SolutionType)[0], 'outlog',
                [])

        if len(getattr(md.results, structure[0].SolutionType)[0].errlog):
            print(
                "loadresultsfromcluster info message: error during solution. Check your errlog and outlog model fields."
            )

        #if only one solution, extract it from list for user friendliness
        if len(structure) == 1 and not m.strcmp(structure[0].SolutionType,
                                                'TransientSolution'):
            setattr(md.results, structure[0].SolutionType, structure[0])

    #post processes qmu results if necessary
    else:
        md = postqmu(md)
        os.chdir('..')

    return md
Ejemplo n.º 15
0
def bamg(md,*args):
	"""
	BAMG - mesh generation

	   Available options (for more details see ISSM website http://issm.jpl.nasa.gov/):

	   - domain :            followed by an ARGUS file that prescribes the domain outline
	   - hmin :              minimum edge length (default is 10^-100)
	   - hmax :              maximum edge length (default is 10^100)
	   - hVertices :         imposed edge length for each vertex (geometry or mesh)
	   - hminVertices :      minimum edge length for each vertex (mesh)
	   - hmaxVertices :      maximum edge length for each vertex (mesh)

	   - anisomax :          maximum ratio between the smallest and largest edges (default is 10^30)
	   - coeff :             coefficient applied to the metric (2-> twice as many elements, default is 1)
	   - cutoff :            scalar used to compute the metric when metric type 2 or 3 are applied
	   - err :               error used to generate the metric from a field
	   - errg :              geometric error (default is 0.1)
	   - field :             field of the model that will be used to compute the metric
	                         to apply several fields, use one column per field
	   - gradation :         maximum ratio between two adjacent edges
	   - Hessiantype :       0 -> use double P2 projection (default)
	                         1 -> use Green formula
	   - KeepVertices :      try to keep initial vertices when adaptation is done on an existing mesh (default 1)
	   - MaxCornerAngle :    maximum angle of corners in degree (default is 10)
	   - maxnbv :            maximum number of vertices used to allocate memory (default is 10^6)
	   - maxsubdiv :         maximum subdivision of exisiting elements (default is 10)
	   - metric :            matrix (numberofnodes x 3) used as a metric
	   - Metrictype :        1 -> absolute error          c/(err coeff^2) * Abs(H)        (default)
	                         2 -> relative error          c/(err coeff^2) * Abs(H)/max(s,cutoff*max(s))
	                         3 -> rescaled absolute error c/(err coeff^2) * Abs(H)/(smax-smin)
	   - nbjacoby :          correction used by Hessiantype=1 (default is 1)
	   - nbsmooth :          number of metric smoothing procedure (default is 3)
	   - omega :             relaxation parameter of the smoothing procedure (default is 1.8)
	   - power :             power applied to the metric (default is 1)
	   - splitcorners :      split triangles whuch have 3 vertices on the outline (default is 1)
	   - geometricalmetric : take the geometry into account to generate the metric (default is 0)
	   - verbose :           level of verbosity (default is 1)

	   - rifts :             followed by an ARGUS file that prescribes the rifts
	   - toltip :            tolerance to move tip on an existing point of the domain outline
	   - tracks :            followed by an ARGUS file that prescribes the tracks that the mesh will stick to
	   - RequiredVertices :  mesh vertices that are required. [x,y,ref]; ref is optional
	   - tol :               if the distance between 2 points of the domain outline is less than tol, they
	                         will be merged

	   Examples:
	      md=bamg(md,'domain','DomainOutline.exp','hmax',3000);
	      md=bamg(md,'field',[md.inversion.vel_obs md.geometry.thickness],'hmax',20000,'hmin',1000);
	      md=bamg(md,'metric',A,'hmin',1000,'hmax',20000,'gradation',3,'anisomax',1);
	"""

	#process options
	options=pairoptions(*args)
#	options=deleteduplicates(options,1);

	#initialize the structures required as input of Bamg
	bamg_options=OrderedDict()
	bamg_geometry=bamggeom()
	bamg_mesh=bamgmesh()

	# Bamg Geometry parameters {{{
	if options.exist('domain'):

		#Check that file exists
		domainfile=options.getfieldvalue('domain')
		if not os.path.exists(domainfile):
			raise IOError("bamg error message: file '%s' not found" % domainfile)
		domain=expread(domainfile)

		#Build geometry 
		count=0
		for i,domaini in enumerate(domain):

			#Check that the domain is closed
			if (domaini['x'][0]!=domaini['x'][-1] or domaini['y'][0]!=domaini['y'][-1]):
				raise RuntimeError("bamg error message: all contours provided in ''domain'' should be closed")

			#Checks that all holes are INSIDE the principle domain outline
			if i:
				flags=ContourToNodes(domaini['x'],domaini['y'],domainfile,0)[0]
				if np.any(np.logical_not(flags)):
					raise RuntimeError("bamg error message: All holes should be strictly inside the principal domain")

			#Add all points to bamg_geometry
			nods=domaini['nods']-1    #the domain are closed 0=end
			bamg_geometry.Vertices=np.vstack((bamg_geometry.Vertices,np.vstack((domaini['x'][0:nods],domaini['y'][0:nods],np.ones((nods)))).T))
			bamg_geometry.Edges   =np.vstack((bamg_geometry.Edges,np.vstack((np.arange(count+1,count+nods+1),np.hstack((np.arange(count+2,count+nods+1),count+1)),1.*np.ones((nods)))).T))
			if i:
				bamg_geometry.SubDomains=np.vstack((bamg_geometry.SubDomains,[2,count+1,1,1]))

			# bamg_geometry.Vertices=np.hstack((bamg_geometry.Vertices,np.vstack((domaini['x'][0:nods].reshape(-1),domaini['y'][0:nods].reshape(-1),np.ones((nods))))))
			# bamg_geometry.Edges   =np.vstack((bamg_geometry.Edges,np.hstack((np.arange(count+1,count+nods+1).reshape(-1,),np.hstack((np.arange(count+2,count+nods+1),count+1)).reshape(-1,),1.*np.ones((nods,))))))
			# if i:
			# 	bamg_geometry.SubDomains=np.vstack((bamg_geometry.SubDomains,[2,count+1,1,1]))

			#update counter
			count+=nods

		#take care of rifts
		if options.exist('rifts'):

			#Check that file exists
			riftfile=options.getfieldvalue('rifts')
			if not os.path.exists(riftfile):
				raise IOError("bamg error message: file '%s' not found" % riftfile)
			rift=expread(riftfile)

			for i,rifti in enumerate(rift):

				#detect whether all points of the rift are inside the domain
				flags=ContourToNodes(rifti['x'],rifti['y'],domain[0],0)[0]
				if np.all(np.logical_not(flags)):
					raise RuntimeError("one rift has all its points outside of the domain outline")

				elif np.any(np.logical_not(flags)):
					#We LOTS of work to do
					print "Rift tip outside of or on the domain has been detected and is being processed..."

					#check that only one point is outside (for now)
					if np.sum(np.logical_not(flags).astype(int))!=1:
						raise RuntimeError("bamg error message: only one point outside of the domain is supported yet")

					#Move tip outside to the first position
					if   not flags[0]:
						#OK, first point is outside (do nothing),
						pass
					elif not flags[-1]:
						rifti['x']=np.flipud(rifti['x'])
						rifti['y']=np.flipud(rifti['y'])
					else:
						raise RuntimeError("bamg error message: only a rift tip can be outside of the domain")

					#Get cordinate of intersection point
					x1=rifti['x'][0]
					y1=rifti['y'][0]
					x2=rifti['x'][1]
					y2=rifti['y'][1]
					for j in xrange(0,np.size(domain[0]['x'])-1):
						if SegIntersect(np.array([[x1,y1],[x2,y2]]),np.array([[domain[0]['x'][j],domain[0]['y'][j]],[domain[0]['x'][j+1],domain[0]['y'][j+1]]])):

							#Get position of the two nodes of the edge in domain
							i1=j
							i2=j+1

							#rift is crossing edge [i1 i2] of the domain
							#Get coordinate of intersection point (http://mathworld.wolfram.com/Line-LineIntersection.html)
							x3=domain[0]['x'][i1]
							y3=domain[0]['y'][i1]
							x4=domain[0]['x'][i2]
							y4=domain[0]['y'][i2]
#							x=det([det([x1 y1; x2 y2])  x1-x2;det([x3 y3; x4 y4])  x3-x4])/det([x1-x2 y1-y2;x3-x4 y3-y4]);
#							y=det([det([x1 y1; x2 y2])  y1-y2;det([x3 y3; x4 y4])  y3-y4])/det([x1-x2 y1-y2;x3-x4 y3-y4]);
							x=np.linalg.det(np.array([[np.linalg.det(np.array([[x1,y1],[x2,y2]])),x1-x2],[np.linalg.det(np.array([[x3,y3],[x4,y4]])),x3-x4]]))/np.linalg.det(np.array([[x1-x2,y1-y2],[x3-x4,y3-y4]]))
							y=np.linalg.det(np.array([[np.linalg.det(np.array([[x1,y1],[x2,y2]])),y1-y2],[np.linalg.det(np.array([[x3,y3],[x4,y4]])),y3-y4]]))/np.linalg.det(np.array([[x1-x2,y1-y2],[x3-x4,y3-y4]]))

							segdis= sqrt((x4-x3)**2+(y4-y3)**2)
							tipdis=np.array([sqrt((x-x3)**2+(y-y3)**2),sqrt((x-x4)**2+(y-y4)**2)])

							if np.min(tipdis)/segdis < options.getfieldvalue('toltip',0):
								print "moving tip-domain intersection point"

								#Get position of the closer point
								if tipdis[0]>tipdis[1]:
									pos=i2
								else:
									pos=i1

								#This point is only in Vertices (number pos).
								#OK, now we can add our own rift
								nods=rifti['nods']-1
								bamg_geometry.Vertices=np.vstack((bamg_geometry.Vertices,np.hstack((rifti['x'][1:].reshape(-1,),rifti['y'][1:].reshape(-1,),np.ones((nods,1))))))
								bamg_geometry.Edges=np.vstack((bamg_geometry.Edges,\
									np.array([[pos,count+1,(1+i)]]),\
									np.hstack((np.arange(count+1,count+nods).reshape(-1,),np.arange(count+2,count+nods+1).reshape(-1,),(1+i)*np.ones((nods-1,1))))))
								count+=nods

								break

							else:
								#Add intersection point to Vertices
								bamg_geometry.Vertices=np.vstack((bamg_geometry.Vertices,np.array([[x,y,1]])))
								count+=1

								#Decompose the crossing edge into 2 subedges
								pos=np.nonzero(np.logical_and(bamg_geometry.Edges[:,0]==i1,bamg_geometry.Edges[:,1]==i2))[0]
								if not pos:
									raise RuntimeError("bamg error message: a problem occurred...")
								bamg_geometry.Edges=np.vstack((bamg_geometry.Edges[0:pos-1,:],\
									np.array([[bamg_geometry.Edges[pos,0],count                     ,bamg_geometry.Edges[pos,2]]]),\
									np.array([[count                     ,bamg_geometry.Edges[pos,1],bamg_geometry.Edges[pos,2]]]),\
									bamg_geometry.Edges[pos+1:,:]))

								#OK, now we can add our own rift
								nods=rifti['nods']-1
								bamg_geometry.Vertices=np.vstack((bamg_geometry.Vertices,np.hstack((rifti['x'][1:].reshape(-1,),rifti['y'][1:].reshape(-1,),np.ones((nods,1))))))
								bamg_geometry.Edges=np.vstack((bamg_geometry.Edges,\
									np.array([[count,count+1,2]]),\
									np.hstack((np.arange(count+1,count+nods).reshape(-1,),np.arange(count+2,count+nods+1).reshape(-1,),(1+i)*np.ones((nods-1,1))))))
								count+=nods

								break

				else:
					nods=rifti['nods']-1
					bamg_geometry.Vertices=np.vstack(bamg_geometry.Vertices, np.hstack(rifti['x'][:],rifti['y'][:],np.ones((nods+1,1))))
					bamg_geometry.Edges   =np.vstack(bamg_geometry.Edges, np.hstack(np.arange(count+1,count+nods).reshape(-1,),np.arange(count+2,count+nods+1).reshape(-1,),i*np.ones((nods,1))))
					count=+nods+1

		#Deal with tracks
		if options.exist('tracks'):

			#read tracks
			track=options.getfieldvalue('tracks')
			if all(isinstance(track,(str,unicode))):
				A=expread(track)
				track=np.hstack((A.x.reshape(-1,),A.y.reshape(-1,)))
			else:
				track=float(track)    #for some reason, it is of class "single"
			if np.size(track,axis=1)==2:
				track=np.hstack((track,3.*np.ones((size(track,axis=0),1))))

			#only keep those inside
			flags=ContourToNodes(track[:,0],track[:,1],domainfile,0)[0]
			track=track[np.nonzero(flags),:]

			#Add all points to bamg_geometry
			nods=np.size(track,axis=0)
			bamg_geometry.Vertices=np.vstack((bamg_geometry.Vertices,track))
			bamg_geometry.Edges   =np.vstack((bamg_geometry.Edges,np.hstack((np.arange(count+1,count+nods).reshape(-1,),np.arange(count+2,count+nods+1).reshape(-1,),3.*np.ones((nods-1,1))))))

			#update counter
			count+=nods

		#Deal with vertices that need to be kept by mesher
		if options.exist('RequiredVertices'):

			#recover RequiredVertices
			requiredvertices=options.getfieldvalue('RequiredVertices')    #for some reason, it is of class "single"
			if np.size(requiredvertices,axis=1)==2:
				requiredvertices=np.hstack((requiredvertices,4.*np.ones((np.size(requiredvertices,axis=0),1))))

			#only keep those inside
			flags=ContourToNodes(requiredvertices[:,0],requiredvertices[:,1],domainfile,0)[0]
			requiredvertices=requiredvertices[np.nonzero(flags)[0],:]
			#Add all points to bamg_geometry
			nods=np.size(requiredvertices,axis=0)
			bamg_geometry.Vertices=np.vstack((bamg_geometry.Vertices,requiredvertices))

			#update counter
			count+=nods

		#process geom
		#bamg_geometry=processgeometry(bamg_geometry,options.getfieldvalue('tol',float(nan)),domain[0])

	elif isinstance(md.private.bamg,dict) and 'geometry' in md.private.bamg:
		bamg_geometry=bamggeom(md.private.bamg['geometry'].__dict__) 
	else:
		#do nothing...
		pass
	#}}}
	# Bamg Mesh parameters {{{
	if not options.exist('domain') and md.mesh.numberofvertices and m.strcmp(md.mesh.elementtype(),'Tria'):

		if isinstance(md.private.bamg,dict) and 'mesh' in md.private.bamg:
			bamg_mesh=bamgmesh(md.private.bamg['mesh'].__dict__)
		else:
			bamg_mesh.Vertices=np.vstack((md.mesh.x,md.mesh.y,np.ones((md.mesh.numberofvertices)))).T
			#bamg_mesh.Vertices=np.hstack((md.mesh.x.reshape(-1,),md.mesh.y.reshape(-1,),np.ones((md.mesh.numberofvertices,1))))
			bamg_mesh.Triangles=np.hstack((md.mesh.elements,np.ones((md.mesh.numberofelements,1))))

		if isinstance(md.rifts.riftstruct,dict):
			raise TypeError("bamg error message: rifts not supported yet. Do meshprocessrift AFTER bamg")
	#}}}
	# Bamg Options {{{
	bamg_options['Crack']=options.getfieldvalue('Crack',0)
	bamg_options['anisomax']=options.getfieldvalue('anisomax',10.**30)
	bamg_options['coeff']=options.getfieldvalue('coeff',1.)
	bamg_options['cutoff']=options.getfieldvalue('cutoff',10.**-5)
	bamg_options['err']=options.getfieldvalue('err',np.array([[0.01]]))
	bamg_options['errg']=options.getfieldvalue('errg',0.1)
	bamg_options['field']=options.getfieldvalue('field',np.empty((0,1)))
	bamg_options['gradation']=options.getfieldvalue('gradation',1.5)
	bamg_options['Hessiantype']=options.getfieldvalue('Hessiantype',0)
	bamg_options['hmin']=options.getfieldvalue('hmin',10.**-100)
	bamg_options['hmax']=options.getfieldvalue('hmax',10.**100)
	bamg_options['hminVertices']=options.getfieldvalue('hminVertices',np.empty((0,1)))
	bamg_options['hmaxVertices']=options.getfieldvalue('hmaxVertices',np.empty((0,1)))
	bamg_options['hVertices']=options.getfieldvalue('hVertices',np.empty((0,1)))
	bamg_options['KeepVertices']=options.getfieldvalue('KeepVertices',1)
	bamg_options['MaxCornerAngle']=options.getfieldvalue('MaxCornerAngle',10.)
	bamg_options['maxnbv']=options.getfieldvalue('maxnbv',10**6)
	bamg_options['maxsubdiv']=options.getfieldvalue('maxsubdiv',10.)
	bamg_options['metric']=options.getfieldvalue('metric',np.empty((0,1)))
	bamg_options['Metrictype']=options.getfieldvalue('Metrictype',0)
	bamg_options['nbjacobi']=options.getfieldvalue('nbjacobi',1)
	bamg_options['nbsmooth']=options.getfieldvalue('nbsmooth',3)
	bamg_options['omega']=options.getfieldvalue('omega',1.8)
	bamg_options['power']=options.getfieldvalue('power',1.)
	bamg_options['splitcorners']=options.getfieldvalue('splitcorners',1)
	bamg_options['geometricalmetric']=options.getfieldvalue('geometricalmetric',0)
	bamg_options['random']=options.getfieldvalue('rand',True)
	bamg_options['verbose']=options.getfieldvalue('verbose',1)
	#}}}

	#call Bamg
	bamgmesh_out,bamggeom_out=BamgMesher(bamg_mesh.__dict__,bamg_geometry.__dict__,bamg_options)

	# plug results onto model
	md.private.bamg=OrderedDict()
	md.private.bamg['mesh']=bamgmesh(bamgmesh_out)
	md.private.bamg['geometry']=bamggeom(bamggeom_out)
	md.mesh = mesh2d()
	md.mesh.x=bamgmesh_out['Vertices'][:,0].copy()
	md.mesh.y=bamgmesh_out['Vertices'][:,1].copy()
	md.mesh.elements=bamgmesh_out['Triangles'][:,0:3].astype(int)
	md.mesh.edges=bamgmesh_out['IssmEdges'].astype(int)
	md.mesh.segments=bamgmesh_out['IssmSegments'][:,0:3].astype(int)
	md.mesh.segmentmarkers=bamgmesh_out['IssmSegments'][:,3].astype(int)

	#Fill in rest of fields:
	md.mesh.numberofelements=np.size(md.mesh.elements,axis=0)
	md.mesh.numberofvertices=np.size(md.mesh.x)
	md.mesh.numberofedges=np.size(md.mesh.edges,axis=0)
	md.mesh.vertexonboundary=np.zeros(md.mesh.numberofvertices,bool)
	md.mesh.vertexonboundary[md.mesh.segments[:,0:2]-1]=True
	md.mesh.elementconnectivity=md.private.bamg['mesh'].ElementConnectivity
	md.mesh.elementconnectivity[np.nonzero(np.isnan(md.mesh.elementconnectivity))]=0
	md.mesh.elementconnectivity=md.mesh.elementconnectivity.astype(int)

	#Check for orphan
	if np.any(np.logical_not(np.in1d(np.arange(1,md.mesh.numberofvertices+1),md.mesh.elements.flat))):
		raise RuntimeError("Output mesh has orphans. Decrease MaxCornerAngle to prevent outside points (ex: 0.01)")

	return md
Ejemplo n.º 16
0
def checkfield(md,*args):
	"""
	CHECKFIELD - check field consistency

	   Used to check model consistency.,
	   Requires: 
	   'field' or 'fieldname' option. If 'fieldname' is provided, it will retrieve it from the model md. (md.(fieldname)) 
             If 'field' is provided, it will assume the argument following 'field' is a numeric array.

	   Available options:
	      - NaN: 1 if check that there is no NaN
	      - size: [lines cols], NaN for non checked dimensions
	      - >:  greater than provided value
	      - >=: greater or equal to provided value
	      - <:  smallerthan provided value
	      - <=: smaller or equal to provided value
	      - < vec:  smallerthan provided values on each vertex
	      - timeseries: 1 if check time series consistency (size and time)
	      - values: cell of strings or vector of acceptable values
	      - numel: list of acceptable number of elements
	      - cell: 1 if check that is cell
	      - empty: 1 if check that non empty
	      - message: overloaded error message

	   Usage:
	      md = checkfield(md,fieldname,options);
	"""

	#get options
	options=pairoptions(*args)

	#get field from model
	if options.exist('field'):
		field=options.getfieldvalue('field')
		fieldname=options.getfieldvalue('fieldname','no fieldname')
	else:
		fieldname=options.getfieldvalue('fieldname') 
		exec("field=md.{}".format(fieldname))

	if isinstance(field,(bool,int,long,float)):
		field=np.array([field])

	#check empty
	if options.exist('empty'):
		if not field:
			md = md.checkmessage(options.getfieldvalue('message',\
				"field '%s' is empty" % fieldname))

	#Check size
	if options.exist('size'):
		fieldsize=options.getfieldvalue('size')
		if len(fieldsize) == 1:
			if np.isnan(fieldsize[0]):
				pass
			elif np.ndim(field)==1:
				if not np.size(field)==fieldsize[0]:
					md = md.checkmessage(options.getfieldvalue('message',"field {} size should be {}".format(fieldname,fieldsize[0])))
			else:
				try:
					 exec("md.{}=field[:,0]".format(fieldname))
					 print('{} had a bad dimension, we fixed it but you should check it'.format(fieldname))
				except IndexError:
					md = md.checkmessage(options.getfieldvalue('message',"field {} should have {} dimension".format(fieldname,len(fieldsize))))
		elif len(fieldsize) == 2:
			if   np.isnan(fieldsize[0]):
				if not np.size(field,1)==fieldsize[1]:
					md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have %d columns" % (fieldname,fieldsize[1])))
			elif np.isnan(fieldsize[1]):
				if not np.size(field,0)==fieldsize[0]:
					md = md.checkmessage(options.getfieldvalue('message',"field '%s' should have %d lines" % (fieldname,fieldsize[0])))
			elif fieldsize[1]==1:
				if (not np.size(field,0)==fieldsize[0]):
					md = md.checkmessage(options.getfieldvalue('message',"field '%s' size should be %d x %d" % (fieldname,fieldsize[0],fieldsize[1])))
			else:
				if (not np.size(field,0)==fieldsize[0]) or (not np.size(field,1)==fieldsize[1]):
					md = md.checkmessage(options.getfieldvalue('message',"field '%s' size should be %d x %d" % (fieldname,fieldsize[0],fieldsize[1])))
	
	#Check numel
	if options.exist('numel'):
		fieldnumel=options.getfieldvalue('numel')
		if np.size(field) not in fieldnumel:
			if   len(fieldnumel)==1:
				md = md.checkmessage(options.getfieldvalue('message',\
					"field '%s' size should be %d" % (fieldname,fieldnumel)))
			elif len(fieldnumel)==2:
				md = md.checkmessage(options.getfieldvalue('message',\
					"field '%s' size should be %d or %d" % (fieldname,fieldnumel[0],fieldnumel[1])))
			else:
				md = md.checkmessage(options.getfieldvalue('message',\
					"field '%s' size should be %s" % (fieldname,fieldnumel)))

	#check NaN
	if options.getfieldvalue('NaN',0):
		if np.any(np.isnan(field)):
			md = md.checkmessage(options.getfieldvalue('message',\
				"NaN values found in field '%s'" % fieldname))

	#check Inf
	if options.getfieldvalue('Inf',0):
		if np.any(np.isinf(field)):
			md = md.checkmessage(options.getfieldvalue('message',\
				"Inf values found in field '%s'" % fieldname))

	#check cell
	if options.getfieldvalue('cell',0):
		if not isinstance(field,(tuple,list,dict)):
			md = md.checkmessage(options.getfieldvalue('message',\
				"field '%s' should be a cell" % fieldname))

	#check values
	if options.exist('values'):
		fieldvalues=options.getfieldvalue('values')
		if False in m.ismember(field,fieldvalues):
			if   len(fieldvalues)==1:
				md = md.checkmessage(options.getfieldvalue('message',\
					"field '%s' value should be '%s'"  % (fieldname,fieldvalues[0])))
			elif len(fieldvalues)==2:
				md = md.checkmessage(options.getfieldvalue('message',\
					"field '%s' values should be '%s' or '%s'"  % (fieldname,fieldvalues[0],fieldvalues[1])))
			else:
				md = md.checkmessage(options.getfieldvalue('message',\
					"field '%s' should have values in %s" % (fieldname,fieldvalues)))

	#check greater
	if options.exist('>='):
		lowerbound=options.getfieldvalue('>=')
		if np.any(field<lowerbound):
			md = md.checkmessage(options.getfieldvalue('message',\
				"field '%s' should have values above %d" % (fieldname,lowerbound)))
	if options.exist('>'):
		lowerbound=options.getfieldvalue('>')
		if np.any(field<=lowerbound):
			md = md.checkmessage(options.getfieldvalue('message',\
				"field '%s' should have values above %d" % (fieldname,lowerbound)))

	#check smaller
	if options.exist('<='):
		upperbound=options.getfieldvalue('<=')
		if np.any(field>upperbound):
			md = md.checkmessage(options.getfieldvalue('message',\
				"field '%s' should have values below %d" % (fieldname,upperbound)))
	if options.exist('<'):
		upperbound=options.getfieldvalue('<')
		if np.any(field>=upperbound):
			md = md.checkmessage(options.getfieldvalue('message',\
				"field '%s' should have values below %d" % (fieldname,upperbound)))

	#check file
	if options.getfieldvalue('file',0):
		if not os.path.exists(field):
			md = md.checkmessage("file provided in '%s': '%s' does not exist" % (fieldname,field))

	#Check row of strings
	if options.exist('stringrow'):
		if not isinstance(field,list):
			md = md.checkmessage(options.getfieldvalue('message',\
					"field '%s' should be a list" %fieldname))

	#Check forcings (size and times)
	if options.getfieldvalue('timeseries',0):
		if   np.size(field,0)==md.mesh.numberofvertices:
			if np.ndim(field)>1 and not np.size(field,1)==1:
				md = md.checkmessage(options.getfieldvalue('message',\
					"field '%s' should have only one column as there are md.mesh.numberofvertices lines" % fieldname))
		elif np.size(field,0)==md.mesh.numberofvertices+1 or np.size(field,0)==2:
			if not all(field[-1,:]==np.sort(field[-1,:])):
				md = md.checkmessage(options.getfieldvalue('message',\
					"field '%s' columns should be sorted chronologically" % fieldname))
			if any(field[-1,0:-1]==field[-1,1:]):
				md = md.checkmessage(options.getfieldvalue('message',\
					"field '%s' columns must not contain duplicate timesteps" % fieldname))
		else:
			md = md.checkmessage(options.getfieldvalue('message',\
				"field '%s' should have md.mesh.numberofvertices or md.mesh.numberofvertices+1 lines" % fieldname))

	#Check single value forcings (size and times)
	if options.getfieldvalue('singletimeseries',0):
		if np.size(field,0)==2:
			if not all(field[-1,:]==np.sort(field[-1,:])):
				md = md.checkmessage(options.getfieldvalue('message',\
						"field '%s' columns should be sorted chronologically" % fieldname))
			if any(field[-1,0:-1]==field[-1,1:]):
				md = md.checkmessage(options.getfieldvalue('message',\
						"field '%s' columns must not contain duplicate timesteps" % fieldname))
		else:
				md = md.checkmessage(options.getfieldvalue('message',\
				"field '%s' should have 2 lines" % fieldname))

	return md
Ejemplo n.º 17
0
def FlagElements(md, region):
    """
	FLAGELEMENTS - flag the elements in an region

	   The region can be given with an exp file, a list of elements or vertices

	   Usage: 
	      flag=FlagElements(md,region);

	   Example:
	      flag=FlagElements(md,'all');
	      flag=FlagElements(md,'');
	      flag=FlagElements(md,'Domain.exp');
	      flag=FlagElements(md,'~Domain.exp');
	"""

    if isinstance(region, (str, unicode)):
        if not region:
            flag = np.zeros(md.mesh.numberofelements, bool)
            invert = 0
        elif m.strcmpi(region, 'all'):
            flag = np.ones(md.mesh.numberofelements, bool)
            invert = 0
        else:
            #make sure that we actually don't want the elements outside the domain outline!
            if m.strcmpi(region[0], '~'):
                region = region[1:]
                invert = 1
            else:
                invert = 0

            #does the region domain outline exist or do we have to look for xlim,ylim in basinzoom?
            if not os.path.exists(region):
                if len(region) > 3 and not m.strcmp(region[-4:], '.exp'):
                    raise IOError("Error: File 'region' not found!" % region)
                raise RuntimeError(
                    "FlagElements.py calling basinzoom.py is not complete.")
                xlim, ylim = basinzoom('basin', region)
                flag_nodes = p.logical_and_n(md.mesh.x < xlim[1],
                                             md.mesh.x > xlim[0],
                                             md.mesh.y < ylim[1],
                                             md.mesh.y > ylim[0])
                flag = np.prod(flag_nodes[md.mesh.elements],
                               axis=1).astype(bool)
            else:
                #ok, flag elements
                flag = ContourToMesh(md.mesh.elements[:,
                                                      0:3].copy(), md.mesh.x,
                                     md.mesh.y, region, 'element', 1)
                flag = flag.astype(bool)

        if invert:
            flag = np.logical_not(flag)

    elif isinstance(region, np.ndarray) or isinstance(region, bool):
        if np.size(region, 0) == md.mesh.numberofelements:
            flag = region
        elif np.size(region, 0) == md.mesh.numberofvertices:
            flag = (np.sum(region[md.mesh.elements - 1] > 0,
                           axis=1) == np.size(md.mesh.elements, 1))
        else:
            raise TypeError(
                "Flaglist for region must be of same size as number of elements in model."
            )

    else:
        raise TypeError("Invalid region option")

    return flag
Ejemplo n.º 18
0
def processgeometry(geom,tol,outline):    # {{{

	raise RuntimeError("bamg.py/processgeometry is not complete.")
	#Deal with edges
	print "Checking Edge crossing..."
	i=0
	while (i<np.size(geom.Edges,axis=0)):

		#edge counter
		i+=1

		#Get coordinates
		x1=geom.Vertices[geom.Edges[i,0],0]
		y1=geom.Vertices[geom.Edges[i,0],1]
		x2=geom.Vertices[geom.Edges[i,1],0]
		y2=geom.Vertices[geom.Edges[i,1],1]
		color1=geom.Edges[i,2]

		j=i    #test edges located AFTER i only
		while (j<np.size(geom.Edges,axis=0)):

			#edge counter
			j+=1

			#Skip if the two edges already have a vertex in common
			if any(m.ismember(geom.Edges[i,0:2],geom.Edges[j,0:2])):
				continue

			#Get coordinates
			x3=geom.Vertices[geom.Edges[j,0],0]
			y3=geom.Vertices[geom.Edges[j,0],1]
			x4=geom.Vertices[geom.Edges[j,1],0]
			y4=geom.Vertices[geom.Edges[j,1],1]
			color2=geom.Edges[j,2]

			#Check if the two edges are crossing one another
			if SegIntersect(np.array([[x1,y1],[x2,y2]]),np.array([[x3,y3],[x4,y4]])):

				#Get coordinate of intersection point (http://mathworld.wolfram.com/Line-LineIntersection.html)
				x=np.linalg.det(np.array([np.linalg.det(np.array([[x1,y1],[x2,y2]])),x1-x2],[np.linalg.det(np.array([[x3,y3],[x4,y4]])),x3-x4])/np.linalg.det(np.array([[x1-x2,y1-y2],[x3-x4,y3-y4]])))
				y=np.linalg.det(np.array([np.linalg.det(np.array([[x1,y1],[x2,y2]])),y1-y2],[np.linalg.det(np.array([[x3,y3],[x4,y4]])),y3-y4])/np.linalg.det(np.array([[x1-x2,y1-y2],[x3-x4,y3-y4]])))

				#Add vertex to the list of vertices
				geom.Vertices=np.vstack((geom.Vertices,[x,y,min(color1,color2)]))
				id=np.size(geom.Vertices,axis=0)

				#Update edges i and j
				edgei=geom.Edges[i,:].copy()
				edgej=geom.Edges[j,:].copy()
				geom.Edges[i,:]    =[edgei(0),id      ,edgei(2)]
				geom.Edges=np.vstack((geom.Edges,[id      ,edgei(1),edgei(2)]))
				geom.Edges[j,:]    =[edgej(0),id      ,edgej(2)]
				geom.Edges=np.vstack((geom.Edges,[id      ,edgej(1),edgej(2)]))

				#update current edge second tip
				x2=x
				y2=y

	#Check point outside
	print "Checking for points outside the domain..."
	i=0
	num=0
	while (i<np.size(geom.Vertices,axis=0)):

		#vertex counter
		i+=1

		#Get coordinates
		x=geom.Vertices[i,0]
		y=geom.Vertices[i,1]
		color=geom.Vertices[i,2]

		#Check that the point is inside the domain
		if color!=1 and not ContourToNodes(x,y,outline[0],1):

			#Remove points from list of Vertices
			num+=1
			geom.Vertices[i,:]=[]

			#update edges
			posedges=np.nonzero(geom.Edges==i)
			geom.Edges[posedges[0],:]=[]
			posedges=np.nonzero(geom.Edges>i)
			geom.Edges[posedges]=geom.Edges[posedges]-1

			#update counter
			i-=1

	if num:
		print "WARNING: %d points outside the domain outline have been removed" % num

	"""
	%Check point spacing
	if ~isnan(tol),
		disp('Checking point spacing...');
		i=0;
		while (i<size(geom.Vertices,1)),

			%vertex counter
			i=i+1;

			%Get coordinates
			x1=geom.Vertices(i,1);
			y1=geom.Vertices(i,2);

			j=i; %test edges located AFTER i only
			while (j<size(geom.Vertices,1)),

				%vertex counter
				j=j+1;

				%Get coordinates
				x2=geom.Vertices(j,1);
				y2=geom.Vertices(j,2);

				%Check whether the two vertices are too close
				if ((x2-x1)**2+(y2-y1)**2<tol**2)

					%Remove points from list of Vertices
					geom.Vertices(j,:)=[];

					%update edges
					posedges=find(m.ismember(geom.Edges,j));
					geom.Edges(posedges)=i;
					posedges=find(geom.Edges>j);
					geom.Edges(posedges)=geom.Edges(posedges)-1;

					%update counter
					j=j-1;

				end
			end
		end
	end
	%remove empty edges
	geom.Edges(find(geom.Edges(:,1)==geom.Edges(:,2)),:)=[];
	"""
	return geom
Ejemplo n.º 19
0
def contourenvelope(md, *args):
    """
	CONTOURENVELOPE - build a set of segments enveloping a contour .exp

	   Usage:
	      segments=contourenvelope(md,varargin)

	   Example:
	      segments=contourenvelope(md,'Stream.exp');
	      segments=contourenvelope(md);
	"""

    #some checks
    if len(args) > 1:
        raise RuntimeError("contourenvelope error message: bad usage")

    if len(args) == 1:
        flags = args[0]

        if isinstance(flags, (str, unicode)):
            file = flags
            if not os.path.exists(file):
                raise IOError(
                    "contourenvelope error message: file '%s' not found" %
                    file)
            isfile = 1
        elif isinstance(flags, (bool, int, long, float)):
            #do nothing for now
            isfile = 0
        else:
            raise TypeError(
                "contourenvelope error message:  second argument should be a file or an elements flag"
            )

    #Now, build the connectivity tables for this mesh.
    #Computing connectivity
    if np.size(md.mesh.vertexconnectivity,
               axis=0) != md.mesh.numberofvertices and np.size(
                   md.mesh.vertexconnectivity,
                   axis=0) != md.mesh.numberofvertices2d:
        md.mesh.vertexconnectivity = NodeConnectivity(
            md.mesh.elements, md.mesh.numberofvertices)[0]
    if np.size(md.mesh.elementconnectivity,
               axis=0) != md.mesh.numberofelements and np.size(
                   md.mesh.elementconnectivity,
                   axis=0) != md.mesh.numberofelements2d:
        md.mesh.elementconnectivity = ElementConnectivity(
            md.mesh.elements, md.mesh.vertexconnectivity)[0]

    #get nodes inside profile
    elementconnectivity = copy.deepcopy(md.mesh.elementconnectivity)
    if md.mesh.dimension() == 2:
        elements = copy.deepcopy(md.mesh.elements)
        x = copy.deepcopy(md.mesh.x)
        y = copy.deepcopy(md.mesh.y)
        numberofvertices = copy.deepcopy(md.mesh.numberofvertices)
        numberofelements = copy.deepcopy(md.mesh.numberofelements)
    else:
        elements = copy.deepcopy(md.mesh.elements2d)
        x = copy.deepcopy(md.mesh.x2d)
        y = copy.deepcopy(md.mesh.y2d)
        numberofvertices = copy.deepcopy(md.mesh.numberofvertices2d)
        numberofelements = copy.deepcopy(md.mesh.numberofelements2d)

    if len(args) == 1:

        if isfile:
            #get flag list of elements and nodes inside the contour
            nodein = ContourToMesh(elements, x, y, file, 'node', 1)
            elemin = (np.sum(nodein(elements), axis=1) == np.size(elements,
                                                                  axis=1))
            #modify element connectivity
            elemout = np.nonzero(np.logical_not(elemin))[0]
            elementconnectivity[elemout, :] = 0
            elementconnectivity[np.nonzero(
                m.ismember(elementconnectivity, elemout + 1))] = 0
        else:
            #get flag list of elements and nodes inside the contour
            nodein = np.zeros(numberofvertices)
            elemin = np.zeros(numberofelements)

            pos = np.nonzero(flags)
            elemin[pos] = 1
            nodein[elements[pos, :] - 1] = 1

            #modify element connectivity
            elemout = np.nonzero(np.logical_not(elemin))[0]
            elementconnectivity[elemout, :] = 0
            elementconnectivity[np.nonzero(
                m.ismember(elementconnectivity, elemout + 1))] = 0

    #Find element on boundary
    #First: find elements on the boundary of the domain
    flag = copy.deepcopy(elementconnectivity)
    if len(args) == 1:
        flag[np.nonzero(flag)] = elemin[flag[np.nonzero(flag)]]
    elementonboundary = np.logical_and(
        np.prod(flag, axis=1) == 0,
        np.sum(flag, axis=1) > 0)

    #Find segments on boundary
    pos = np.nonzero(elementonboundary)[0]
    num_segments = np.size(pos)
    segments = np.zeros((num_segments * 3, 3), int)
    count = 0

    for el1 in pos:
        els2 = elementconnectivity[
            el1, np.nonzero(elementconnectivity[el1, :])[0]] - 1
        if np.size(els2) > 1:
            flag = np.intersect1d(
                np.intersect1d(elements[els2[0], :], elements[els2[1], :]),
                elements[el1, :])
            nods1 = elements[el1, :]
            nods1 = np.delete(nods1, np.nonzero(nods1 == flag))
            segments[count, :] = [nods1[0], nods1[1], el1 + 1]

            ord1 = np.nonzero(nods1[0] == elements[el1, :])[0][0]
            ord2 = np.nonzero(nods1[1] == elements[el1, :])[0][0]

            #swap segment nodes if necessary
            if ((ord1 == 0 and ord2 == 1) or (ord1 == 1 and ord2 == 2)
                    or (ord1 == 2 and ord2 == 0)):
                temp = segments[count, 0]
                segments[count, 0] = segments[count, 1]
                segments[count, 1] = temp
            segments[count, 0:2] = np.flipud(segments[count, 0:2])
            count += 1
        else:
            nods1 = elements[el1, :]
            flag = np.setdiff1d(nods1, elements[els2, :])
            for j in xrange(0, 3):
                nods = np.delete(nods1, j)
                if np.any(m.ismember(flag, nods)):
                    segments[count, :] = [nods[0], nods[1], el1 + 1]
                    ord1 = np.nonzero(nods[0] == elements[el1, :])[0][0]
                    ord2 = np.nonzero(nods[1] == elements[el1, :])[0][0]
                    if ((ord1 == 0 and ord2 == 1) or (ord1 == 1 and ord2 == 2)
                            or (ord1 == 2 and ord2 == 0)):
                        temp = segments[count, 0]
                        segments[count, 0] = segments[count, 1]
                        segments[count, 1] = temp
                    segments[count, 0:2] = np.flipud(segments[count, 0:2])
                    count += 1
    segments = segments[0:count, :]

    return segments
Ejemplo n.º 20
0
def WriteData(fid, prefix, *args):
    """
	WRITEDATA - write model field in binary file
 
	   Usage:
	      WriteData(fid,varargin)
	"""

    #process options
    options = pairoptions(*args)

    #Get data properties
    if options.exist('object'):
        #This is an object field, construct enum and data
        obj = options.getfieldvalue('object')
        fieldname = options.getfieldvalue('fieldname')
        classname = options.getfieldvalue(
            'class',
            str(type(obj)).rsplit('.')[-1].split("'")[0])
        name = options.getfieldvalue('name', prefix + '.' + fieldname)
        if options.exist('data'):
            data = options.getfieldvalue('data')
        else:
            data = getattr(obj, fieldname)
    else:
        #No processing required
        data = options.getfieldvalue('data')
        name = options.getfieldvalue('name')

    format = options.getfieldvalue('format')
    mattype = options.getfieldvalue('mattype', 0)  #only required for matrices
    timeserieslength = options.getfieldvalue('timeserieslength', -1)

    #Process sparse matrices
    #	if issparse(data),
    #		data=full(data);
    #	end

    #Scale data if necesarry
    if options.exist('scale'):
        scale = options.getfieldvalue('scale')
        if np.size(data) > 1:
            if np.size(data, 0) == timeserieslength:
                data = np.array(data)
                data[0:-1, :] = scale * data[0:-1, :]
            else:
                data = scale * data
        else:
            data = scale * data
    if np.size(data) > 1:
        if np.size(data, 0) == timeserieslength:
            yts = options.getfieldvalue('yts')
            data[-1, :] = yts * data[-1, :]

    #Step 1: write the enum to identify this record uniquely
    fid.write(struct.pack('i', len(name)))
    fid.write(struct.pack('%ds' % len(name), name))

    #Step 2: write the data itself.
    if m.strcmpi(format, 'Boolean'):  # {{{
        #		if len(data) !=1:
        #			raise ValueError('field %s cannot be marshalled as it has more than one element!' % name[0])

        #first write length of record
        fid.write(struct.pack('i', 4 + 4))  #1 bool (disguised as an int)+code

        #write data code:
        fid.write(struct.pack('i', FormatToCode(format)))

        #now write integer
        fid.write(struct.pack(
            'i', int(data)))  #send an int, not easy to send a bool
        # }}}

    elif m.strcmpi(format, 'Integer'):  # {{{
        #		if len(data) !=1:
        #			raise ValueError('field %s cannot be marshalled as it has more than one element!' % name[0])

        #first write length of record
        fid.write(struct.pack('i', 4 + 4))  #1 integer + code

        #write data code:
        fid.write(struct.pack('i', FormatToCode(format)))

        #now write integer
        fid.write(struct.pack('i', data))
        # }}}

    elif m.strcmpi(format, 'Double'):  # {{{
        #		if len(data) !=1:
        #			raise ValueError('field %s cannot be marshalled as it has more than one element!' % name[0])

        #first write length of record
        fid.write(struct.pack('i', 8 + 4))  #1 double+code

        #write data code:
        fid.write(struct.pack('i', FormatToCode(format)))

        #now write double
        fid.write(struct.pack('d', data))
        # }}}

    elif m.strcmpi(format, 'String'):  # {{{
        #first write length of record
        fid.write(struct.pack('i',
                              len(data) + 4 + 4))  #string + string size + code

        #write data code:
        fid.write(struct.pack('i', FormatToCode(format)))

        #now write string
        fid.write(struct.pack('i', len(data)))
        fid.write(struct.pack('%ds' % len(data), data))
        # }}}

    elif m.strcmpi(format, 'BooleanMat'):  # {{{

        if isinstance(data, bool):
            data = np.array([data])
        elif isinstance(data, (list, tuple)):
            data = np.array(data).reshape(-1, )
        if np.ndim(data) == 1:
            if np.size(data):
                data = data.reshape(np.size(data), )
            else:
                data = data.reshape(0, 0)

        #Get size
        s = data.shape
        #if matrix = NaN, then do not write anything
        if np.ndim(data) == 2 and np.product(s) == 1 and np.all(
                np.isnan(data)):
            s = (0, 0)

        #first write length of record
        fid.write(struct.pack(
            'i', 4 + 4 + 8 * np.product(s) + 4 +
            4))  #2 integers (32 bits) + the double matrix + code + matrix type

        #write data code and matrix type:
        fid.write(struct.pack('i', FormatToCode(format)))
        fid.write(struct.pack('i', mattype))

        #now write matrix
        if np.ndim(data) == 1:
            fid.write(struct.pack('i', s[0]))
            fid.write(struct.pack('i', 1))
            for i in xrange(s[0]):
                fid.write(struct.pack('d', float(
                    data[i])))  #get to the "c" convention, hence the transpose
        else:
            fid.write(struct.pack('i', s[0]))
            fid.write(struct.pack('i', s[1]))
            for i in xrange(s[0]):
                for j in xrange(s[1]):
                    fid.write(struct.pack('d', float(
                        data[i]
                        [j])))  #get to the "c" convention, hence the transpose
        # }}}

    elif m.strcmpi(format, 'IntMat'):  # {{{

        if isinstance(data, (int, long)):
            data = np.array([data])
        elif isinstance(data, (list, tuple)):
            data = np.array(data).reshape(-1, )
        if np.ndim(data) == 1:
            if np.size(data):
                data = data.reshape(np.size(data), )
            else:
                data = data.reshape(0, 0)

        #Get size
        s = data.shape
        #if matrix = NaN, then do not write anything
        if np.ndim(data) == 2 and np.product(s) == 1 and np.all(
                np.isnan(data)):
            s = (0, 0)

        #first write length of record
        fid.write(struct.pack(
            'i', 4 + 4 + 8 * np.product(s) + 4 +
            4))  #2 integers (32 bits) + the double matrix + code + matrix type

        #write data code and matrix type:
        fid.write(struct.pack('i', FormatToCode(format)))
        fid.write(struct.pack('i', mattype))

        #now write matrix
        if np.ndim(data) == 1:
            fid.write(struct.pack('i', s[0]))
            fid.write(struct.pack('i', 1))
            for i in xrange(s[0]):
                fid.write(struct.pack('d', float(
                    data[i])))  #get to the "c" convention, hence the transpose
        else:
            fid.write(struct.pack('i', s[0]))
            fid.write(struct.pack('i', s[1]))
            for i in xrange(s[0]):
                for j in xrange(s[1]):
                    fid.write(struct.pack('d', float(
                        data[i]
                        [j])))  #get to the "c" convention, hence the transpose
        # }}}

    elif m.strcmpi(format, 'DoubleMat'):  # {{{

        if isinstance(data, (bool, int, long, float)):
            data = np.array([data])
        elif isinstance(data, (list, tuple)):
            data = np.array(data).reshape(-1, )
        if np.ndim(data) == 1:
            if np.size(data):
                data = data.reshape(np.size(data), )
            else:
                data = data.reshape(0, 0)

        #Get size
        s = data.shape
        #if matrix = NaN, then do not write anything
        if np.ndim(data) == 1 and np.product(s) == 1 and np.all(
                np.isnan(data)):
            s = (0, 0)

        #first write length of record
        recordlength = 4 + 4 + 8 * np.product(s) + 4 + 4
        #2 integers (32 bits) + the double matrix + code + matrix type
        if recordlength > 4**31:
            raise ValueError(
                'field %s cannot be marshalled because it is larger than 4^31 bytes!'
                % enum)

        fid.write(
            struct.pack('i', recordlength)
        )  #2 integers (32 bits) + the double matrix + code + matrix type

        #write data code and matrix type:
        fid.write(struct.pack('i', FormatToCode(format)))
        fid.write(struct.pack('i', mattype))

        #now write matrix
        if np.ndim(data) == 1:
            fid.write(struct.pack('i', s[0]))
            fid.write(struct.pack('i', 1))
            for i in xrange(s[0]):
                fid.write(struct.pack('d', float(
                    data[i])))  #get to the "c" convention, hence the transpose
        else:
            fid.write(struct.pack('i', s[0]))
            fid.write(struct.pack('i', s[1]))
            for i in xrange(s[0]):
                for j in xrange(s[1]):
                    fid.write(struct.pack('d', float(
                        data[i]
                        [j])))  #get to the "c" convention, hence the transpose
        # }}}

    elif m.strcmpi(format, 'CompressedMat'):  # {{{

        if isinstance(data, (bool, int, long, float)):
            data = np.array([data])
        elif isinstance(data, (list, tuple)):
            data = np.array(data).reshape(-1, )
        if np.ndim(data) == 1:
            if np.size(data):
                data = data.reshape(np.size(data), )
            else:
                data = data.reshape(0, 0)

        #Get size
        s = data.shape
        if np.ndim(data) == 1:
            n2 = 1
        else:
            n2 = s[1]

        #if matrix = NaN, then do not write anything
        if np.ndim(data) == 1 and np.product(s) == 1 and np.all(
                np.isnan(data)):
            s = (0, 0)
            n2 = 0

        #first write length of record
        recordlength = 4 + 4 + 8 + 8 + 1 * (
            s[0] - 1
        ) * n2 + 8 * n2 + 4 + 4  #2 integers (32 bits) + the matrix + code + matrix type
        if recordlength > 4**31:
            raise ValueError(
                'field %s cannot be marshalled because it is larger than 4^31 bytes!'
                % enum)

        fid.write(struct.pack('i', recordlength)
                  )  #2 integers (32 bits) + the matrix + code + matrix type

        #write data code and matrix type:
        fid.write(struct.pack('i', FormatToCode(format)))
        fid.write(struct.pack('i', mattype))

        #Write offset and range
        A = data[0:s[0] - 1]
        offsetA = A.min()
        rangeA = A.max() - offsetA

        if rangeA == 0:
            A = A * 0
        else:
            A = (A - offsetA) / rangeA * 255.

        #now write matrix
        if np.ndim(data) == 1:
            fid.write(struct.pack('i', s[0]))
            fid.write(struct.pack('i', 1))
            fid.write(struct.pack('d', float(offsetA)))
            fid.write(struct.pack('d', float(rangeA)))
            for i in xrange(s[0] - 1):
                fid.write(struct.pack('B', int(A[i])))

            fid.write(struct.pack('d', float(
                data[s[0] -
                     1])))  #get to the "c" convention, hence the transpose

        elif np.product(s) > 0:
            fid.write(struct.pack('i', s[0]))
            fid.write(struct.pack('i', s[1]))
            fid.write(struct.pack('d', float(offsetA)))
            fid.write(struct.pack('d', float(rangeA)))
            for i in xrange(s[0] - 1):
                for j in xrange(s[1]):
                    fid.write(struct.pack('B', int(
                        A[i]
                        [j])))  #get to the "c" convention, hence the transpose

            for j in xrange(s[1]):
                fid.write(struct.pack('d', float(data[s[0] - 1][j])))

        # }}}

    elif m.strcmpi(format, 'MatArray'):  # {{{

        #first get length of record
        recordlength = 4 + 4  #number of records + code
        for matrix in data:
            if isinstance(matrix, (bool, int, long, float)):
                matrix = np.array([matrix])
            elif isinstance(matrix, (list, tuple)):
                matrix = np.array(matrix).reshape(-1, )
            if np.ndim(matrix) == 1:
                if np.size(matrix):
                    matrix = matrix.reshape(np.size(matrix), )
                else:
                    matrix = matrix.reshape(0, 0)

            s = matrix.shape
            recordlength += 4 * 2 + np.product(
                s) * 8  #row and col of matrix + matrix of doubles

        #write length of record
        fid.write(struct.pack('i', recordlength))

        #write data code:
        fid.write(struct.pack('i', FormatToCode(format)))

        #write data, first number of records
        fid.write(struct.pack('i', len(data)))

        #write each matrix:
        for matrix in data:
            if isinstance(matrix, (bool, int, long, float)):
                matrix = np.array([matrix])
            elif isinstance(matrix, (list, tuple)):
                matrix = np.array(matrix).reshape(-1, )
            if np.ndim(matrix) == 1:
                matrix = matrix.reshape(np.size(matrix), )

            s = matrix.shape
            if np.ndim(data) == 1:
                fid.write(struct.pack('i', s[0]))
                fid.write(struct.pack('i', 1))
                for i in xrange(s[0]):
                    fid.write(
                        struct.pack('d', float(matrix[i]))
                    )  #get to the "c" convention, hence the transpose
            else:
                fid.write(struct.pack('i', s[0]))
                fid.write(struct.pack('i', s[1]))
                for i in xrange(s[0]):
                    for j in xrange(s[1]):
                        fid.write(struct.pack('d', float(matrix[i][j])))
        # }}}

    elif m.strcmpi(format, 'StringArray'):  # {{{

        #first get length of record
        recordlength = 4 + 4  #for length of array + code
        for string in data:
            recordlength += 4 + len(string)  #for each string

        #write length of record
        fid.write(struct.pack('i', recordlength))

        #write data code:
        fid.write(struct.pack('i', FormatToCode(format)))

        #now write length of string array
        fid.write(struct.pack('i', len(data)))

        #now write the strings
        for string in data:
            fid.write(struct.pack('i', len(string)))
            fid.write(struct.pack('%ds' % len(string), string))
        # }}}

    else:  # {{{
        raise TypeError(
            'WriteData error message: data type: %d not supported yet! (%s)' %
            (format, enum))
Ejemplo n.º 21
0
    def extract(md, area):  # {{{
        """
		extract - extract a model according to an Argus contour or flag list

		   This routine extracts a submodel from a bigger model with respect to a given contour
		   md must be followed by the corresponding exp file or flags list
		   It can either be a domain file (argus type, .exp extension), or an array of element flags. 
		   If user wants every element outside the domain to be 
		   extract2d, add '~' to the name of the domain file (ex: '~HO.exp')
		   an empty string '' will be considered as an empty domain
		   a string 'all' will be considered as the entire domain

		   Usage:
		      md2=extract(md,area)

		   Examples:
		      md2=extract(md,'Domain.exp')

		   See also: EXTRUDE, COLLAPSE
		"""

        #copy model
        md1 = copy.deepcopy(md)

        #get elements that are inside area
        flag_elem = FlagElements(md1, area)
        if not np.any(flag_elem):
            raise RuntimeError("extracted model is empty")

        #kick out all elements with 3 dirichlets
        spc_elem = np.nonzero(np.logical_not(flag_elem))[0]
        spc_node = np.unique(md1.mesh.elements[spc_elem, :]) - 1
        flag = np.ones(md1.mesh.numberofvertices)
        flag[spc_node] = 0
        pos = np.nonzero(
            np.logical_not(np.sum(flag[md1.mesh.elements - 1], axis=1)))[0]
        flag_elem[pos] = 0

        #extracted elements and nodes lists
        pos_elem = np.nonzero(flag_elem)[0]
        pos_node = np.unique(md1.mesh.elements[pos_elem, :]) - 1

        #keep track of some fields
        numberofvertices1 = md1.mesh.numberofvertices
        numberofelements1 = md1.mesh.numberofelements
        numberofvertices2 = np.size(pos_node)
        numberofelements2 = np.size(pos_elem)
        flag_node = np.zeros(numberofvertices1)
        flag_node[pos_node] = 1

        #Create Pelem and Pnode (transform old nodes in new nodes and same thing for the elements)
        Pelem = np.zeros(numberofelements1, int)
        Pelem[pos_elem] = np.arange(1, numberofelements2 + 1)
        Pnode = np.zeros(numberofvertices1, int)
        Pnode[pos_node] = np.arange(1, numberofvertices2 + 1)

        #renumber the elements (some node won't exist anymore)
        elements_1 = copy.deepcopy(md1.mesh.elements)
        elements_2 = elements_1[pos_elem, :]
        elements_2[:, 0] = Pnode[elements_2[:, 0] - 1]
        elements_2[:, 1] = Pnode[elements_2[:, 1] - 1]
        elements_2[:, 2] = Pnode[elements_2[:, 2] - 1]
        if md1.mesh.__class__.__name__ == 'mesh3dprisms':
            elements_2[:, 3] = Pnode[elements_2[:, 3] - 1]
            elements_2[:, 4] = Pnode[elements_2[:, 4] - 1]
            elements_2[:, 5] = Pnode[elements_2[:, 5] - 1]

        #OK, now create the new model!

        #take every field from model
        md2 = copy.deepcopy(md1)

        #automatically modify fields

        #loop over model fields
        model_fields = vars(md1)
        for fieldi in model_fields:
            #get field
            field = getattr(md1, fieldi)
            fieldsize = np.shape(field)
            if hasattr(field, '__dict__') and not m.ismember(
                    fieldi, ['results'])[0]:  #recursive call
                object_fields = vars(field)
                for fieldj in object_fields:
                    #get field
                    field = getattr(getattr(md1, fieldi), fieldj)
                    fieldsize = np.shape(field)
                    if len(fieldsize):
                        #size = number of nodes * n
                        if fieldsize[0] == numberofvertices1:
                            setattr(getattr(md2, fieldi), fieldj,
                                    field[pos_node])
                        elif fieldsize[0] == numberofvertices1 + 1:
                            setattr(getattr(md2, fieldi), fieldj,
                                    np.vstack((field[pos_node], field[-1, :])))
                        #size = number of elements * n
                        elif fieldsize[0] == numberofelements1:
                            setattr(getattr(md2, fieldi), fieldj,
                                    field[pos_elem])
            else:
                if len(fieldsize):
                    #size = number of nodes * n
                    if fieldsize[0] == numberofvertices1:
                        setattr(md2, fieldi, field[pos_node])
                    elif fieldsize[0] == numberofvertices1 + 1:
                        setattr(md2, fieldi,
                                np.hstack((field[pos_node], field[-1, :])))
                    #size = number of elements * n
                    elif fieldsize[0] == numberofelements1:
                        setattr(md2, fieldi, field[pos_elem])

        #modify some specific fields

        #Mesh
        md2.mesh.numberofelements = numberofelements2
        md2.mesh.numberofvertices = numberofvertices2
        md2.mesh.elements = elements_2

        #mesh.uppervertex mesh.lowervertex
        if md1.mesh.__class__.__name__ == 'mesh3dprisms':
            md2.mesh.uppervertex = md1.mesh.uppervertex[pos_node]
            pos = np.where(~np.isnan(md2.mesh.uppervertex))[0]
            md2.mesh.uppervertex[pos] = Pnode[
                md2.mesh.uppervertex[pos].astype(int) - 1]

            md2.mesh.lowervertex = md1.mesh.lowervertex[pos_node]
            pos = np.where(~np.isnan(md2.mesh.lowervertex))[0]
            md2.mesh.lowervertex[pos] = Pnode[
                md2.mesh.lowervertex[pos].astype(int) - 1]

            md2.mesh.upperelements = md1.mesh.upperelements[pos_elem]
            pos = np.where(~np.isnan(md2.mesh.upperelements))[0]
            md2.mesh.upperelements[pos] = Pelem[
                md2.mesh.upperelements[pos].astype(int) - 1]

            md2.mesh.lowerelements = md1.mesh.lowerelements[pos_elem]
            pos = np.where(~np.isnan(md2.mesh.lowerelements))[0]
            md2.mesh.lowerelements[pos] = Pelem[
                md2.mesh.lowerelements[pos].astype(int) - 1]

        #Initial 2d mesh
        if md1.mesh.__class__.__name__ == 'mesh3dprisms':
            flag_elem_2d = flag_elem[np.arange(0, md1.mesh.numberofelements2d)]
            pos_elem_2d = np.nonzero(flag_elem_2d)[0]
            flag_node_2d = flag_node[np.arange(0, md1.mesh.numberofvertices2d)]
            pos_node_2d = np.nonzero(flag_node_2d)[0]

            md2.mesh.numberofelements2d = np.size(pos_elem_2d)
            md2.mesh.numberofvertices2d = np.size(pos_node_2d)
            md2.mesh.elements2d = md1.mesh.elements2d[pos_elem_2d, :]
            md2.mesh.elements2d[:, 0] = Pnode[md2.mesh.elements2d[:, 0] - 1]
            md2.mesh.elements2d[:, 1] = Pnode[md2.mesh.elements2d[:, 1] - 1]
            md2.mesh.elements2d[:, 2] = Pnode[md2.mesh.elements2d[:, 2] - 1]

            md2.mesh.x2d = md1.mesh.x[pos_node_2d]
            md2.mesh.y2d = md1.mesh.y[pos_node_2d]

        #Edges
        if m.strcmp(md.mesh.domaintype(), '2Dhorizontal'):
            if np.ndim(md2.mesh.edges) > 1 and np.size(
                    md2.mesh.edges, axis=1
            ) > 1:  #do not use ~isnan because there are some np.nans...
                #renumber first two columns
                pos = np.nonzero(md2.mesh.edges[:, 3] != -1)[0]
                md2.mesh.edges[:, 0] = Pnode[md2.mesh.edges[:, 0] - 1]
                md2.mesh.edges[:, 1] = Pnode[md2.mesh.edges[:, 1] - 1]
                md2.mesh.edges[:, 2] = Pelem[md2.mesh.edges[:, 2] - 1]
                md2.mesh.edges[pos, 3] = Pelem[md2.mesh.edges[pos, 3] - 1]
                #remove edges when the 2 vertices are not in the domain.
                md2.mesh.edges = md2.mesh.edges[np.nonzero(
                    np.logical_and(md2.mesh.edges[:, 0], md2.mesh.edges[:, 1])
                )[0], :]
                #Replace all zeros by -1 in the last two columns
                pos = np.nonzero(md2.mesh.edges[:, 2] == 0)[0]
                md2.mesh.edges[pos, 2] = -1
                pos = np.nonzero(md2.mesh.edges[:, 3] == 0)[0]
                md2.mesh.edges[pos, 3] = -1
                #Invert -1 on the third column with last column (Also invert first two columns!!)
                pos = np.nonzero(md2.mesh.edges[:, 2] == -1)[0]
                md2.mesh.edges[pos, 2] = md2.mesh.edges[pos, 3]
                md2.mesh.edges[pos, 3] = -1
                values = md2.mesh.edges[pos, 1]
                md2.mesh.edges[pos, 1] = md2.mesh.edges[pos, 0]
                md2.mesh.edges[pos, 0] = values
                #Finally remove edges that do not belong to any element
                pos = np.nonzero(
                    np.logical_and(md2.mesh.edges[:, 1] == -1,
                                   md2.mesh.edges[:, 2] == -1))[0]
                md2.mesh.edges = np.delete(md2.mesh.edges, pos, axis=0)

        #Penalties
        if np.any(np.logical_not(np.isnan(md2.stressbalance.vertex_pairing))):
            for i in xrange(np.size(md1.stressbalance.vertex_pairing, axis=0)):
                md2.stressbalance.vertex_pairing[i, :] = Pnode[
                    md1.stressbalance.vertex_pairing[i, :]]
            md2.stressbalance.vertex_pairing = md2.stressbalance.vertex_pairing[
                np.nonzero(md2.stressbalance.vertex_pairing[:, 0])[0], :]
        if np.any(np.logical_not(np.isnan(md2.masstransport.vertex_pairing))):
            for i in xrange(np.size(md1.masstransport.vertex_pairing, axis=0)):
                md2.masstransport.vertex_pairing[i, :] = Pnode[
                    md1.masstransport.vertex_pairing[i, :]]
            md2.masstransport.vertex_pairing = md2.masstransport.vertex_pairing[
                np.nonzero(md2.masstransport.vertex_pairing[:, 0])[0], :]

        #recreate segments
        if md1.mesh.__class__.__name__ == 'mesh2d':
            md2.mesh.vertexconnectivity = NodeConnectivity(
                md2.mesh.elements, md2.mesh.numberofvertices)[0]
            md2.mesh.elementconnectivity = ElementConnectivity(
                md2.mesh.elements, md2.mesh.vertexconnectivity)[0]
            md2.mesh.segments = contourenvelope(md2)
            md2.mesh.vertexonboundary = np.zeros(numberofvertices2, bool)
            md2.mesh.vertexonboundary[md2.mesh.segments[:, 0:2] - 1] = True
        else:
            #First do the connectivity for the contourenvelope in 2d
            md2.mesh.vertexconnectivity = NodeConnectivity(
                md2.mesh.elements2d, md2.mesh.numberofvertices2d)[0]
            md2.mesh.elementconnectivity = ElementConnectivity(
                md2.mesh.elements2d, md2.mesh.vertexconnectivity)[0]
            segments = contourenvelope(md2)
            md2.mesh.vertexonboundary = np.zeros(
                numberofvertices2 / md2.mesh.numberoflayers, bool)
            md2.mesh.vertexonboundary[segments[:, 0:2] - 1] = True
            md2.mesh.vertexonboundary = np.tile(md2.mesh.vertexonboundary,
                                                md2.mesh.numberoflayers)
            #Then do it for 3d as usual
            md2.mesh.vertexconnectivity = NodeConnectivity(
                md2.mesh.elements, md2.mesh.numberofvertices)[0]
            md2.mesh.elementconnectivity = ElementConnectivity(
                md2.mesh.elements, md2.mesh.vertexconnectivity)[0]

        #Boundary conditions: Dirichlets on new boundary
        #Catch the elements that have not been extracted
        orphans_elem = np.nonzero(np.logical_not(flag_elem))[0]
        orphans_node = np.unique(md1.mesh.elements[orphans_elem, :]) - 1
        #Figure out which node are on the boundary between md2 and md1
        nodestoflag1 = np.intersect1d(orphans_node, pos_node)
        nodestoflag2 = Pnode[nodestoflag1].astype(int) - 1
        if np.size(md1.stressbalance.spcvx) > 1 and np.size(
                md1.stressbalance.spcvy) > 2 and np.size(
                    md1.stressbalance.spcvz) > 2:
            if np.size(md1.inversion.vx_obs) > 1 and np.size(
                    md1.inversion.vy_obs) > 1:
                md2.stressbalance.spcvx[nodestoflag2] = md2.inversion.vx_obs[
                    nodestoflag2]
                md2.stressbalance.spcvy[nodestoflag2] = md2.inversion.vy_obs[
                    nodestoflag2]
            else:
                md2.stressbalance.spcvx[nodestoflag2] = np.nan
                md2.stressbalance.spcvy[nodestoflag2] = np.nan
                print "\n!! extract warning: spc values should be checked !!\n\n"
            #put 0 for vz
            md2.stressbalance.spcvz[nodestoflag2] = 0
        if np.any(np.logical_not(np.isnan(md1.thermal.spctemperature))):
            md2.thermal.spctemperature[nodestoflag2] = 1

        #Results fields
        if md1.results:
            md2.results = results()
            for solutionfield, field in md1.results.__dict__.iteritems():
                if isinstance(field, list):
                    setattr(md2.results, solutionfield, [])
                    #get time step
                    for i, fieldi in enumerate(field):
                        if isinstance(fieldi, results) and fieldi:
                            getattr(md2.results,
                                    solutionfield).append(results())
                            fieldr = getattr(md2.results, solutionfield)[i]
                            #get subfields
                            for solutionsubfield, subfield in fieldi.__dict__.iteritems(
                            ):
                                if np.size(subfield) == numberofvertices1:
                                    setattr(fieldr, solutionsubfield,
                                            subfield[pos_node])
                                elif np.size(subfield) == numberofelements1:
                                    setattr(fieldr, solutionsubfield,
                                            subfield[pos_elem])
                                else:
                                    setattr(fieldr, solutionsubfield, subfield)
                        else:
                            getattr(md2.results, solutionfield).append(None)
                elif isinstance(field, results):
                    setattr(md2.results, solutionfield, results())
                    if isinstance(field, results) and field:
                        fieldr = getattr(md2.results, solutionfield)
                        #get subfields
                        for solutionsubfield, subfield in field.__dict__.iteritems(
                        ):
                            if np.size(subfield) == numberofvertices1:
                                setattr(fieldr, solutionsubfield,
                                        subfield[pos_node])
                            elif np.size(subfield) == numberofelements1:
                                setattr(fieldr, solutionsubfield,
                                        subfield[pos_elem])
                            else:
                                setattr(fieldr, solutionsubfield, subfield)

        #Keep track of pos_node and pos_elem
        md2.mesh.extractedvertices = pos_node + 1
        md2.mesh.extractedelements = pos_elem + 1

        return md2