branton
I need different peak-shape functions for the parent and superlattice peaks of an occupancy-ordered superstructure. One approach that I am exploring would require the ability to test a linear combination of H, K and L to see if it is an even integer, an odd integer, or a non-integer value. Can this be done? And if not, what else might work?
Branton Campbell
johnsoevans
Branton,
I'll do my usual trick of answering a slightly different question for speed! Do you know the type of language below? Does it help?
They are just some old lines I had lying around. The key ones are the various "Ifs" and "Mods". If I was doing this now I probably wouldn't use a full PV type expression, just a size or strain broadening. Alan may have other examples in the manual.
The expression below allows two different PV functions; one for one category of reflections, one for another. In this case parameters pkb are used for reflections with h=even, k=1, l=odd .
prm pka1 0.02035_5.01996 min 0.0001 max = 2 Val + .1;
prm pka2 0.09689_0.01863 min 0.0001 max = 2 Val + .1;
prm pka3 0.07010_0.04855 min 0.0001 max = 2 Val + .1;
prm pka4 0.00010_0.49070 min 0.0001 max 1;
prm pka5 7.43367_0.36626 min 0.0001 max = 2 Val + .1;
prm pka6 0.00010_0.49581 min 0.0001 max = 2 Val + .1;
prm pkb1 0.02016_0.04563 min 0.0001 max = 2 Val + .1;
prm pkb2 0.16236_0.11429 min 0.0001 max = 2 Val + .1;
prm pkb3 0.30312_0.06595 min 0.0001 max = 2 Val + .1;
prm pkb4 0.00034_1.12620 min 0.0001 max 1;
prm pkb5 7.88454_0.50652 min 0.0001 max = 2 Val + .1;
prm pkb6 0.00010_1.14741 min 0.0001 max = 2 Val + .1;
peak_type pv pv_lor = If(And(Mod(H,2)==0,K==1,Mod(L,2)==1),(pkb4) + (pkb5) Tan(Th) + (pkb6) / Cos(Th),(pka4) + (pka5) Tan(Th) + (pka6) / Cos(Th)); pv_fwhm = If(And(Mod(H,2)==0,K==1,Mod(L,2)==1),(pkb1) + (pkb2) Tan(Th) + (pkb3) / Cos(Th),(pka1) + (pka2) Tan(Th) + (pka3) / Cos(Th));
alternatively you could just make the (h11) reflections broader than the others
peak_type pv pv_lor = If(And(K==1,L==1),(pkb4) + (pkb5) Tan(Th) + (pkb6) / Cos(Th),(pka4) + (pka5) Tan(Th) + (pka6) / Cos(Th)); pv_fwhm = If(And(K==1,L==1),(pkb1) + (pkb2) Tan(Th) + (pkb3) / Cos(Th),(pka1) + (pka2) Tan(Th) + (pka3) / Cos(Th));
or make the (111) (211) (310) and (510) reflections broad:
peak_type pv pv_lor = If(Or(And(H==1,K==1,L==1),And(H==2,K==2,L==1),And(H==3,K==1,L==0),And(H==4,K==1,L==0),And(H==5,K==3,L==0)),(pkb4) + (pkb5) Tan(Th) + (pkb6) / Cos(Th),(pka4) + (pka5) Tan(Th) + (pka6) / Cos(Th)); pv_fwhm = If(Or(And(H==1,K==1,L==1),And(H==2,K==2,L==1),And(H==3,K==1,L==0),And(H==4,K==1,L==0),And(H==5,K==3,L==0)),(pkb1) + (pkb2) Tan(Th) + (pkb3) / Cos(Th),(pka1) + (pka2) Tan(Th) + (pka3) / Cos(Th));
branton
Thanks John,
That was a very good trick. We struggled for a couple of days until we realized that Mod only works correctly with non-negative integers (the workaround is to employ Abs inside of Mod), but prevailed in the end (see code below).
Branton
lor_fwhm = If(
And( And(Mod(H,2)==0,Mod(K,2)==0), Or( And(Mod(Abs(K-(2*L)),4)==2,Mod((K+(2*L)),4)==2,Mod(H,4)==2), And(Mod(Abs(K-(2*L)),4)==0,Mod((K+(2*L)),4)==0,Mod(H,4)==0) ) ),
(pLw) + (pLst) Tan(Th) + (pLcs) / Cos(Th),
(sLw) + (sLst) Tan(Th) + (sLcs) / Cos(Th)
);
johnsoevans
Branton,
Nice! We should transfer to the wiki as it's likely to be of use to others.
john
branton
This was really just a good-enough workaround for a specific problem. Perhaps the problem with non-negative integers in Mod should be fixed so that the approach works in general situations.
alancoelho
"Perhaps the problem with non-negative integers in Mod should be fixed so that the approach works in general situations."
Thanks Branton for picking this up. The Mod function used is simply the fmod function of c. It is the case however that Mod as defined mathematically is different. Looking at the net I see definitions such as:
"The Mod function is defined as the amount by which a number
exceeds the largest integer multiple of the divisor that is
not greater than that number."
which I think is what Mathematica returns when Mod is used with two arguments.
I think I should modify Mod to be compliant with mathematics but I will also include an FMod which is sufficient in most cases and it is much faster to calculate.
It is a problem however as it may break existing user defined macros.
cheers
alan
junliang
I copied this part below in my inp file in TOPAS 4.1, and they all look reasonable for me but i got an error message
"Maybe an equations starting with an equal sign and
ending in a semicolon is what is meant."
What is the problem?
solved now. The semicolon after "Max 1" should be deleted.
prm pka1 0.02035_5.01996 min 0.0001 max = 2 Val + .1;
prm pka2 0.09689_0.01863 min 0.0001 max = 2 Val + .1;
prm pka3 0.07010_0.04855 min 0.0001 max = 2 Val + .1;
prm pka4 0.00010_0.49070 min 0.0001 max 1;
prm pka5 7.43367_0.36626 min 0.0001 max = 2 Val + .1;
prm pka6 0.00010_0.49581 min 0.0001 max = 2 Val + .1;
prm pkb1 0.02016_0.04563 min 0.0001 max = 2 Val + .1;
prm pkb2 0.16236_0.11429 min 0.0001 max = 2 Val + .1;
prm pkb3 0.30312_0.06595 min 0.0001 max = 2 Val + .1;
prm pkb4 0.00034_1.12620 min 0.0001 max 1;
prm pkb5 7.88454_0.50652 min 0.0001 max = 2 Val + .1;
prm pkb6 0.00010_1.14741 min 0.0001 max = 2 Val + .1;
peak_type pv pv_lor = If(And(Mod(H,2)==0,K==1,Mod(L,2)==1),(pkb4) + (pkb5) Tan(Th) + (pkb6) / Cos(Th),(pka4) + (pka5) Tan(Th) + (pka6) / Cos(Th)); pv_fwhm = If(And(Mod(H,2)==0,K==1,Mod(L,2)==1),(pkb1) + (pkb2) Tan(Th) + (pkb3) / Cos(Th),(pka1) + (pka2) Tan(Th) + (pka3) / Cos(Th));