I have a problem which people better versed than me in Fenics can probably solve quickly, and I'd appreciate it very much. I am trying to define a spatially dependent elasticity tensor (C_ijkl). After assembling the tensor, when I plot a particular component of it (let's say C_1100) using the fenics plot command then it works but if I try to evaluate it at some point within the domain then I get an error. The code is:
mesh = Mesh("geometry.xml")
cd = MeshFunction('size_t',mesh,"geometry_physical_region.xml")
def readMP2():
with open('Material.txt', 'r') as f:
N=([int(x) for x in f.readline().split()])[0];
rhoL=[];
for i, line in enumerate(f):
if i==N-1:
break
rhoL.append(([float(x) for x in line.split()])[0])
rhoL.append(([float(x) for x in line.split()])[0])
rho=np.asarray(rhoL)
lmL=[];
for i, line in enumerate(f):
lmL.append(([float(x) for x in line.split()])[:2])
if i==N-1:
break
lm=np.asarray(lmL)
return (rho,lm)
r,lm = readMP2()
V0=FunctionSpace(mesh, 'DG', 0)
M0=TensorFunctionSpace(mesh, 'DG', 0, shape=(2,2,2,2))
rho,lam,mu=Function(V0),Function(V0),Function(V0)
C=Function(M0)
i=Index()
j=Index()
k=Index()
l=Index()
delta=Identity(2)
rho.vector()[:] = numpy.choose(numpy.asarray(cd.array(), dtype=numpy.int32), r)
lam.vector()[:] = numpy.choose(numpy.asarray(cd.array(), dtype=numpy.int32), lm[:,0])
mu.vector()[:] = numpy.choose(numpy.asarray(cd.array(), dtype=numpy.int32), lm[:,1])
C=as_tensor((lam*(delta[i,j]*delta[k,l])+mu*(delta[i,k]*delta[j,l]+delta[i,l]*delta[j,k])),[i,j,k,l])
After this the following works:
plot(C[1,1,0,0])
interactive()
But if I try to do the following:
C1=C[0,0,0,0]
print C1(.0001,.0001)
then I get the following error:
ufl.log.UFLException: Expecting dim to match the geometric dimension, got dim=1 and gdim=2.
I feel like I am missing something rather trivial. Any light on this would be very appreciated
Related
I'm trying to translatethe following lines of code from Python to MATLAB. V, Id, and J are of size (6400,) which in MATLAB are 1 -by- 6400 row vectors. pts is of size 242.
My Python code
A = coo_matrix((V, (Id, J)), shape=(pts.size, pts.size)).tocsr()
A = A.tobsr(blocksize=(2, 2))
I translated the first line as follows to MATLAB
A = sparse(V,Id,J,242,242);
However, I got the error
Error using sparse
Index into matrix must be an integer.
How can I translate this code to MATLAB?
The MATLAB sparse function has several forms:
S = sparse(A)
S = sparse(m,n)
S = sparse(i,j,v)
S = sparse(i,j,v,m,n)
S = sparse(i,j,v,m,n,nz)
The form you are most likely looking for is the fourth one: S = sparse(i,j,v,m,n), and will want to call it (using your use case) as:
A = sparse(Id, J, V, 242, 242);
I think your error is that MATLAB wants the I and J indices first, followed by the value and you are making the value the first argument.
I am working on Ironpython in Revit application.
This is the code below I was trying in python. Help would be appreciated.
From the list of points, there is a first point and second point. I have created functions for them.
The script should check if the y coordinates are same and draw line if true.
Its not working and returning unexpected error - new line error.
`The inputs to this node will be stored as a list in the IN variables.`
points = IN[0]
`# Place your code below this line`
lines = []
def fp(x)
firstpoint = points[x]
return firstpoint
def sp(x)
secondpoint = points[x+1]
return secondpoint
x = 0
while x <= points.Count:
if (fp(x).Y == sp(x).Y) or (fp(x).Z == sp(x).Z):
setlines = Line.ByStartPointEndPoint(fp(x), sp(x))
lines.append(setlines)
x = x + 1
`# Assign your output to the OUT variable.`
OUT = lines
As #itprorh66 points out, there's really not enough info here to definitively answer your question, but one issue is you're incorrectly comparing what I assume are floats.
fp(x).Y == sp(x).Y
Instead of comparing for direct equality, you'll need to compare for equality within a tolerance. Here is some discussion on how to do that, What is the best way to compare floats for almost-equality in Python?
I tried making a question on this earlier and did a horrible job of explaining what I wanted. Hopefully the information I provide in this one is more helpful.
The program I am trying to make will take read input from a file in the form of the following: (there will be multiple varying test cases)
7 10
4 8
The program will assign a variable to the top-right integer (in this case, 10) and the bottom-left integer (4). The program will then compute the difference of the two variables. Here is the code I have so far -
with open('C:\\Users\\ayush\\Desktop\\USACO\\paint\\paint_test.in', 'r') as fn:
matrix = fn.readlines()
input_array = []
for line in matrix:
input_array.append(line.strip())
for p,q in enumerate(input_array):
for x,y in enumerate(p):
pass
for a,b in enumerate(q):
pass
print(y - a)
When I, however, run this code I get the following error:
Traceback (most recent call last):
File "C:\Users\ayush\Desktop\USACO\paint\paint.py", line 16, in <module>
for x,y in enumerate(p):
TypeError: 'int' object is not iterable
[Finished in 0.571s]
I'm not sure as to what the problem is, and why my lists cannot be iterated.
I hope I did a better job explaining my goal this time. Please let me know if there are any additional details I could try to provide. I would really appreciate some help - I've been stuck on this for the longest time.
Thanks!
Were you going for something along the lines of:
with open('C:\\Users\\ayush\\Desktop\\USACO\\paint\\paint_test.in', 'r') as fn:
matrix = fn.readlines()
input_array = []
for line in matrix:
input_array.append(line.strip())
top_line, bottom_line = input_array # previously p, q
top_right, top_left = top_line.split() # previously x, y
bottom_right, bottom_lefft = bottom_line.split() # previously a, b
print(int(top_left) - int(bottom_right)) # you would have run into issue subtracting strings without the int() calls
?
If so, that should work, but you can avoid all the unpacking if you just use [0] and [-1] indexes to get the first and last items (this has the advantage of working on a matrix of any size):
with open('C:\\Users\\ayush\\Desktop\\USACO\\paint\\paint_test.in', 'r') as fn:
lines = fn.read().splitlines()
matrix = [
[
int(item)
for item in line.split()
]
for line in lines
]
top_left = matrix[0][-1]
bottom_right = matrix[-1][0]
print(top_left - bottom_right)
I am working on a problem which involves a batch of 19 tokens each with 400 features. I get the shape (19,1,400) when concatenating two vectors of size (1, 200) into the final feature vector. If I squeeze the 1 out I am left with (19,) but I am trying to get (19,400). I have tried converting to list, squeezing and raveling but nothing has worked.
Is there a way to convert this array to the correct shape?
def attn_output_concat(sample):
out_h, state_h = get_output_and_state_history(agent.model, sample)
attns = get_attentions(state_h)
inner_outputs = get_inner_outputs(state_h)
if len(attns) != len(inner_outputs):
print 'Length err'
else:
tokens = [np.zeros((400))] * largest
print(tokens.shape)
for j, (attns_token, inner_token) in enumerate(zip(attns, inner_outputs)):
tokens[j] = np.concatenate([attns_token, inner_token], axis=1)
print(np.array(tokens).shape)
return tokens
The easiest way would be to declare tokens to be a numpy.shape=(19,400) array to start with. That's also more memory/time efficient. Here's the relevant portion of your code revised...
import numpy as np
attns_token = np.zeros(shape=(1,200))
inner_token = np.zeros(shape=(1,200))
largest = 19
tokens = np.zeros(shape=(largest,400))
for j in range(largest):
tokens[j] = np.concatenate([attns_token, inner_token], axis=1)
print(tokens.shape)
BTW... It makes it difficult for people to help you if you don't include a self-contained and runnable segment of code (which is probably why you haven't gotten a response on this yet). Something like the above snippet is preferred and will help you get better answers because there's less guessing at what your trying to accomplish.
I have a simple, stupid Python problem. Given a graph, I'm trying to sample from a random variable whose distribution is the same as that of the degree distribution of the graph.
This seems like it should pretty straightforward. Yet somehow I am still managing to mess this up. My code looks like this:
import numpy as np
import scipy as sp
import graph_tool.all as gt
G = gt.random_graph(500, deg_sampler=lambda: np.random.poisson(1), directed=False)
deg = gt.vertex_hist(G,"total",float_count=False)
# Extract counts and values
count = list(deg[0])
value = list(deg[1])
# Generate vector of probabilities for each node
p = [float(x)/sum(count) for x in count]
# Load into a random variable for sampling
x = sp.stats.rv_discrete(values=(value,p))
print x.rvs(1)
However, upon running this it returns an error:
Traceback (most recent call last):
File "temp.py", line 16, in <module>
x = sp.stats.rv_discrete(values=(value,p))
File "/usr/lib/python2.7/dist-packages/scipy/stats/distributions.py", line 5637, in __init__
self.pk = take(ravel(self.pk),indx, 0)
File "/usr/lib/python2.7/dist-packages/numpy/core/fromnumeric.py", line 103, in take
return take(indices, axis, out, mode)
IndexError: index out of range for array
I'm not sure why this is. If in the code above I write instead:
x = sp.stats.rv_discrete(values=(range(len(count)),p))
Then the code runs fine, but it gives a weird result--clearly the way I've specified this distribution, a value of "0" ought to be most common. But this code gives "1" with high probability and never returns a "0," so something is getting shifted over somehow.
Can anyone clarify what is going on here? Any help would be greatly appreciated!
I believe the first argument for x.rvs() would be the loc arg. If you make loc=1 by calling x.rvs(1), you're adding 1 to all values.
Instead, you want
x.rvs(size=1)
As an aside, I'd recommend that you replace this:
# Extract counts and values
count = list(deg[0])
value = list(deg[1])
# Generate vector of probabilities for each node
p = [float(x)/sum(count) for x in count]
With:
count, value = deg # automatically unpacks along first axis
p = count.astype(float) / count.sum() # count is an array, so you can divide all elements at once